![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
sip3funcs.h File Reference
Version 3 of chan_sip
Olle E. Johansson <oej@edvina.net> (all the chan_sip3 changes)
Definition in file sip3funcs.h.
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Defines | |
| #define | GNURK |
Functions | |
| GNURK const char * | __get_header (struct sip_request *req, const char *name, int *start) |
| GNURK void | __sip_ack (struct sip_dialog *dialog, int seqno, int resp, int sipmethod, int reset) |
| For a reliable transmission, we need to get an reply to stop retransmission. Acknowledges receipt of a packet and stops retransmission. | |
| GNURK void | __sip_destroy (struct sip_dialog *p, int lockowner, int lockdialoglist) |
| Execute destruction of SIP dialog structure, release memory. | |
| GNURK void | __sip_pretend_ack (struct sip_dialog *p) |
| Pretend to ack all packets - nothing to do with SIP_ACK (the method) maybe the lock on p is not strictly necessary but there might be a race. | |
| GNURK int | __sip_semi_ack (struct sip_dialog *p, int seqno, int resp, int sipmethod) |
| Acks receipt of packet, keep it around (used for provisional responses). | |
| GNURK int | __transmit_response (struct sip_dialog *p, const char *msg, struct sip_request *req, enum xmittype reliable) |
| Base transmit response function. | |
| GNURK void | add_blank (struct sip_request *req) |
| add a blank line if no body | |
| GNURK int | add_digit (struct sip_request *req, char digit, unsigned int duration) |
| Add DTMF INFO tone to sip message. | |
| GNURK int | add_header (struct sip_request *req, const char *var, const char *value) |
| Add header to SIP message. | |
| GNURK int | add_header_contentLength (struct sip_request *req, int len) |
| Add 'Content-Length' header to SIP message. | |
| GNURK int | add_line (struct sip_request *req, const char *line) |
| Add content (not header) to SIP message. | |
| GNURK struct sip_auth * | add_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno) |
| Add realm authentication in list. | |
| GNURK void | add_route (struct sip_request *req, struct sip_route *route) |
| Add route header into request per learned route. | |
| GNURK int | add_sdp (struct sip_request *resp, struct sip_dialog *p) |
| Add Session Description Protocol message. | |
| GNURK int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
| Add SIP domain to list of domains we are responsible for. | |
| GNURK int | add_t38_sdp (struct sip_request *resp, struct sip_dialog *p) |
| Add T.38 Session Description Protocol message. | |
| GNURK int | add_text (struct sip_request *req, const char *text) |
| Add text body to SIP message. | |
| GNURK void | append_date (struct sip_request *req) |
| Append date to SIP message. | |
| GNURK void | append_history_full (struct sip_dialog *p, const char *fmt,...) |
| Append to SIP dialog history with arg list. | |
| GNURK void | append_history_va (struct sip_dialog *p, const char *fmt, va_list ap) |
| Append to SIP dialog history with arg list. | |
| GNURK void | append_maxforwards (struct sip_request *req) |
| Append Max-Forwards header to request. | |
| GNURK void | ast_quiet_chan (struct ast_channel *chan) |
| Turn off generator data XXX Does this function belong in the SIP channel? | |
| GNURK void | auth_headers (enum sip_auth_type code, char **header, char **respheader) |
| return the request and response heade for a 401 or 407 code | |
| GNURK void | build_callid_pvt (struct sip_dialog *pvt) |
| Build SIP Call-ID value for a non-REGISTER transaction. | |
| GNURK void | build_contact (struct sip_dialog *p) |
| Build contact header - the contact header we send out. | |
| GNURK int | build_reply_digest (struct sip_dialog *p, int method, char *digest, int digest_len) |
| Build reply digest. | |
| GNURK void | build_rpid (struct sip_dialog *p) |
| Build the Remote Party-ID & From using callingpres options. | |
| GNURK void | build_via (struct sip_dialog *p, int forcenewbranch) |
| Build a Via header for a request. | |
| GNURK enum check_auth_result | check_auth (struct sip_dialog *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore) |
| Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
| GNURK int | check_sip_domain (const char *domain, char *context, size_t len) |
| check_sip_domain: Check if domain part of uri is local to our server | |
| GNURK int | clear_realm_authentication (struct sip_auth *authlist) |
| Clear realm authentication list (at reload). | |
| GNURK void | clear_sip_domains (void) |
| Clear our domain list (at reload). | |
| GNURK int | close_sip_sockets (void) |
| Close all open network sockets. | |
| GNURK char * | complete_sip_device (const char *word, int state, int flags2) |
| Do completion on peer name. | |
| GNURK char * | complete_sip_show_device (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show peer' CLI. | |
| GNURK int | copy_all_header (struct sip_request *req, struct sip_request *orig, const char *field) |
| Copy all headers from one request to another. | |
| GNURK int | copy_header (struct sip_request *req, struct sip_request *orig, const char *field) |
| Copy one header field from one request to another. | |
| GNURK void | copy_request (struct sip_request *dst, const struct sip_request *src) |
| copy SIP request (mostly used to save request for responses) | |
| GNURK int | copy_via_headers (struct sip_dialog *p, struct sip_request *req, struct sip_request *orig, const char *field) |
| Copy SIP VIA Headers from the request to the response. | |
| GNURK int | create_addr (struct sip_dialog *dialog, const char *username, char *domain, const char *device) |
| create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success | |
| GNURK void | destroy_association (struct sip_device *peer) |
| Remove registration data from realtime database or AST/DB when registration expires. | |
| GNURK int | determine_firstline_parts (struct sip_request *req) |
| Parse first line of incoming SIP request. | |
| GNURK struct sip_device * | device_ref (struct sip_device *device) |
| Add reference for device. | |
| GNURK int | device_status (struct sip_device *peer, char *status, int statuslen) |
| Report Device status in character string. | |
| GNURK void | device_unref (struct sip_device *device) |
| Remove reference for device. When we reach 0, device is removed from memory. | |
| GNURK void | dialog_lock (struct sip_dialog *dialog, int state) |
| Helper function to lock and unlock, hiding the underlying locking mechanism. | |
| GNURK void | dialoglist_lock (void) |
| Lock list of active SIP dialogs. | |
| GNURK void | dialoglist_unlock (void) |
| Unlock list of active SIP dialogs. | |
| GNURK const char * | dialogstate2str (const enum dialogstate state) |
| Convert SIP dialog states to string. | |
| GNURK void | dialogstatechange (struct sip_dialog *dialog, enum dialogstate newstate) |
| Change dialog state for a SIP dialog and output to debug. | |
| GNURK int | do_proxy_auth (struct sip_dialog *p, struct sip_request *req, enum sip_auth_type code, int sipmethod, int init) |
| Add authentication on outbound SIP packet. | |
| GNURK int | do_register_auth (struct sip_dialog *p, struct sip_request *req, enum sip_auth_type code) |
| Authenticate for outbound registration. | |
| GNURK void | do_setnat (struct sip_dialog *p, int natflags) |
| Set nat mode on the various media streams. | |
| void * | do_sip_monitor (void *data) |
| The SIP monitoring thread. | |
| GNURK const char * | domain_mode_to_text (const enum domain_mode mode) |
| Print domain mode to cli. | |
| GNURK int | domains_configured (void) |
| return TRUE if any domains are configured for this server | |
| GNURK int | expire_register (void *data) |
| Expire registration of SIP peer. | |
| GNURK void | extract_uri (struct sip_dialog *p, struct sip_request *req) |
| Check Contact: URI of SIP message. | |
| GNURK const char * | find_alias (const char *name, const char *_default) |
| Find compressed SIP alias Structure for conversion between compressed SIP and "normal" SIP. | |
| GNURK struct sip_device * | find_device (const char *peer, struct sockaddr_in *sin, int realtime) |
| Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name. | |
| GNURK struct sip_auth * | find_realm_authentication (struct sip_auth *authlist, const char *realm) |
| Find authentication for a specific realm. | |
| GNURK int | find_sdp (struct sip_request *req) |
| Determine whether a SIP message contains an SDP in its body. | |
| GNURK int | find_sip_method (const char *msg) |
| find_sip_method: Find SIP method from header | |
| GNURK const struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
| Find subscription type in array. | |
| GNURK void | find_via_branch (struct sip_request *req, char *viabuf, size_t vialen) |
| Find via branch parameter. | |
| GNURK void | free_old_route (struct sip_route *route) |
| Remove route from route list. | |
| GNURK int | func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
| Dial plan function to check if domain is local. | |
| GNURK char * | generate_random_string (char *buf, size_t size) |
| Generate 32 byte random string for callid's etc. | |
| GNURK char * | get_body (struct sip_request *req, char *name) |
| Get the message body part identified by name=. | |
| GNURK char * | get_calleridname (const char *input, char *output, size_t outputsize) |
| Get caller id name from SIP headers. | |
| GNURK int | get_destination (struct sip_dialog *p, struct sip_request *oreq) |
| Find out who the call is for We use the INVITE request uri to find out Runs a dialplan lookup. | |
| GNURK const char * | get_header (struct sip_request *req, const char *name) |
| Get header from SIP request. | |
| GNURK char * | get_in_brackets (char *tmp) |
| Pick out text in brackets from character string. | |
| GNURK int | get_rdnis (struct sip_dialog *p, struct sip_request *oreq) |
| Get referring dnis. | |
| GNURK int | get_rpid_num (const char *input, char *output, int maxlen) |
| Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found. | |
| GNURK struct sip_dialog * | get_sip_dialog_byid_locked (const char *callid, const char *totag, const char *fromtag) |
Lock dialog list lock and find matching pvt lock
| |
| GNURK const char * | gettag (const char *header, char *tagbuf, int tagbufsize) |
| Get tag from packet. | |
| GNURK int | handle_request (struct sip_dialog *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
| Handle incoming SIP requests (methods). | |
| GNURK int | handle_request_refer (struct sip_dialog *p, struct sip_request *req, int debug, int seqno, int *nounlock) |
| void | handle_response_peerpoke (struct sip_dialog *p, int resp, struct sip_request *req) |
| Handle qualification responses (OPTIONS). | |
| GNURK int | handle_response_register (struct sip_dialog *p, int resp, char *rest, struct sip_request *req, int seqno) |
| Handle responses on REGISTER to services. | |
| GNURK const char * | hangup_cause2sip (int cause) |
| Convert Asterisk hangup causes to SIP codes. | |
| GNURK int | hangup_sip2cause (int cause) |
| Convert SIP hangup causes to Asterisk hangup causes. | |
| GNURK int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
| Initialize SIP request. | |
| GNURK int | init_resp (struct sip_request *resp, const char *msg) |
| Initialize SIP response, based on SIP request. | |
| GNURK void | initialize_initreq (struct sip_dialog *p, struct sip_request *req) |
| Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
| GNURK void | initreqprep (struct sip_request *req, struct sip_dialog *p, int sipmethod) |
| Initiate new SIP request to peer/user. | |
| void | kill_monitor (void) |
| kill monitor thread (only at module unload) | |
| GNURK void | logdebug (int level, const char *fmt,...) |
| Append to SIP dialog history with arg list. | |
| GNURK int | lws2sws (char *msgbuf, int len) |
| Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
| GNURK void | make_our_tag (char *tagbuf, size_t len) |
| Make our SIP dialog tag. | |
| GNURK int | manager_sip_show_device (struct mansession *s, const struct message *m) |
| Show SIP peers in the manager API. | |
| GNURK int | manager_sip_show_devices (struct mansession *s, const struct message *m) |
| Show SIP peers in the manager API. | |
| GNURK struct sip_dialog * | match_or_create_dialog (struct sip_request *req, struct sockaddr_in *sin, const int intended_method) |
| GNURK int | method_match (enum sipmethod id, const char *name) |
| returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
| GNURK void | parse_moved_contact (struct sip_dialog *p, struct sip_request *req) |
| Parse 302 Moved temporalily response. | |
| GNURK void | parse_request (struct sip_request *req) |
| Parse a SIP message. | |
| GNURK unsigned int | parse_sip_options (struct sip_dialog *pvt, const char *supported) |
| Parse supported header in incoming packet. | |
| GNURK void | print_group (int fd, ast_group_t group, int crlf) |
| Print call group and pickup group. | |
| GNURK int | process_sdp (struct sip_dialog *p, struct sip_request *req) |
| Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call. | |
| GNURK struct sip_device * | realtime_peer (const char *newpeername, struct sockaddr_in *sin) |
| realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf | |
| GNURK void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expiry) |
| Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
| GNURK const char * | referstatus2str (enum referstatus rstatus) attribute_pure |
| Convert transfer status to string. | |
| GNURK void | reg_source_db (struct sip_device *peer) |
| GNURK void | register_peer_exten (struct sip_device *device, int onoff) |
| Automatically add peer extension to dial plan. | |
| GNURK void | register_rtp_and_udptl (void) |
| Register RTP and UDPTL to the subsystems. | |
| GNURK char * | regstate2str (enum sipregistrystate regstate) attribute_const |
| Convert registration state status to string. | |
| GNURK int | reload_config (enum channelreloadreason reason) |
| Re-read SIP.conf config file. | |
| GNURK void | replace_cid (struct sip_dialog *p, const char *rpid_num, const char *calleridname) |
| helper function for check_{user|peer}_ok() | |
| GNURK int | reply_digest (struct sip_dialog *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
| reply to authentication for outbound registrations | |
| GNURK int | reqprep (struct sip_request *req, struct sip_dialog *p, int sipmethod, int seqno, int newbranch) |
| Initialize a SIP request message (not the initial one in a dialog). | |
| GNURK void | reset_ip_interface (struct sip_network *sipsock) |
| clear IP interfaces | |
| GNURK int | respprep (struct sip_request *resp, struct sip_dialog *p, const char *msg, struct sip_request *req) |
| Prepare SIP response packet. | |
| int | restart_monitor (void) |
| Start the channel monitor thread. | |
| GNURK int | send_request (struct sip_dialog *p, struct sip_request *req, enum xmittype reliable) |
| Send SIP Request to the other part of the dialogue. | |
| GNURK int | send_response (struct sip_dialog *p, struct sip_request *req, enum xmittype reliable) |
| Transmit response on SIP request. | |
| GNURK void | set_device_defaults (struct sip_device *device) |
| Set peer defaults before configuring specific configurations. | |
| GNURK void | set_initreq (struct sip_dialog *dialog, struct sip_request *req) |
| Set packet to initreq status. Set flag to avoid de-allocation until dialog is destroyed. | |
| GNURK struct sip_dialog * | sip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
| Allocate SIP_PVT structure and set defaults. | |
| GNURK void | sip_cancel_destroy (struct sip_dialog *p) |
| Cancel destruction of SIP dialog. | |
| GNURK void | sip_cli_and_manager_commands_register (void) |
| Register cli and manager commands. | |
| GNURK void | sip_cli_and_manager_commands_unregister (void) |
| Unregister cli and manager commands. | |
| GNURK int | sip_debug_test_addr (const struct sockaddr_in *addr) |
| See if we pass debug IP filter. | |
| GNURK int | sip_debug_test_pvt (struct sip_dialog *p) |
| Test PVT for debugging output. | |
| GNURK void | sip_destroy (struct sip_dialog *p) |
| Destroy SIP call structure. | |
| GNURK void | sip_destroy_device (struct sip_device *peer) |
| Destroy device object from memory. | |
| GNURK int | sip_do_reload (void) |
| Reload module. | |
| GNURK void | sip_dump_history (struct sip_dialog *dialog) |
| Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
| GNURK enum ast_rtp_get_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
| Returns null if we can't reinvite audio (part of RTP interface). | |
| GNURK enum ast_rtp_get_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
| Returns null if we can't reinvite video (part of RTP interface). | |
| GNURK int | sip_listconfigs (int fd) |
| List all configuration options in sip.conf. | |
| GNURK char * | sip_method2txt (int method) |
| return text string for sip method | |
| GNURK int | sip_method_needrtp (int method) |
| Check whether method needs RTP. | |
| GNURK const char * | sip_nat_mode (const struct sip_dialog *p) |
| Display SIP nat mode. | |
| GNURK int | sip_notify (int fd, int argc, char *argv[]) |
| GNURK char * | sip_option2text (int option) |
| Return text representation of SIP option. | |
| GNURK int | sip_option_lookup (const char *optionlabel) |
| Check if sip option is known to us, avoid x- options (non-standard). | |
| GNURK void | sip_options_print (int options, int fd) |
| Print options to cli. | |
| GNURK int | sip_ouraddrfor (struct in_addr *them, struct in_addr *us) |
| NAT fix - decide which IP address to use for Asterisk server? | |
| GNURK void | sip_peer_hold (struct sip_dialog *p, int hold) |
| Change onhold state of a peer using a pvt structure. | |
| void | sip_poke_all_peers (void) |
| Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
| int | sip_poke_noanswer (void *data) |
| React to lack of answer to Qualify poke. | |
| int | sip_poke_peer (struct sip_device *peer) |
| Check availability of peer, also keep NAT open. | |
| int | sip_poke_peer_s (void *data) |
| Poke peer (send qualify to check if peer is alive and well). | |
| GNURK int | sip_prune_realtime (int fd, int argc, char *argv[]) |
| Remove temporary realtime objects from memory (CLI). | |
| GNURK struct ast_frame * | sip_read (struct ast_channel *ast) |
| Read SIP RTP from channel. | |
| GNURK const struct sockaddr_in * | sip_real_dst (const struct sip_dialog *p) |
| The real destination address for a write. | |
| GNURK int | sip_refer_allocate (struct sip_dialog *p) |
| Allocate SIP refer structure. | |
| GNURK int | sip_register (char *value, int lineno, struct sip_device *peer) |
| Parse register=> line in sip.conf and add to registry. | |
| GNURK void | sip_registry_destroy (struct sip_registry *reg) |
| Destroy registry object Objects created with the register= statement in static configuration. | |
| GNURK int | sip_reload (int fd) |
| Force reload of module from cli. | |
| GNURK int | sip_reload_check (void) |
| GNURK void | sip_scheddestroy (struct sip_dialog *p, int ms) |
| Schedule destruction of SIP dialog. | |
| GNURK void | sip_send_all_registers (void) |
| Send all known registrations. | |
| GNURK int | sip_send_mwi_to_peer (struct sip_device *peer) |
| Send message waiting indication to alert peer that they've got voicemail. | |
| GNURK int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
| Set the RTP peer for this call. | |
| GNURK int | sip_show_domains (int fd, int argc, char *argv[]) |
| CLI command to list local domains. | |
| GNURK void | sipnet_lock (struct sip_network *sipnet) |
| Lock netlock. | |
| GNURK int | sipnet_ourport (struct sip_network *sipnet) |
| read our port number | |
| GNURK void | sipnet_ourport_set (struct sip_network *sipnet, int port) |
| Set our port number. | |
| GNURK void | sipnet_unlock (struct sip_network *sipnet) |
| Unlock netlock. | |
| GNURK struct sip_request * | siprequest_alloc (size_t len, struct sip_network *sipnet) |
| Allocate SIP request structure. | |
| GNURK void | siprequest_free (struct sip_request *req) |
| Free SIP request. | |
| GNURK int | sipsock_init (struct sip_network *sipsock, struct sockaddr_in *old_bindappr) |
| Initialize IP socket on configured address - the bind address. | |
| GNURK int | sipsock_read (int *id, int fd, short events, void *ignore) |
| Read data from SIP socket. | |
| GNURK int | sipsocket_initialized (struct sip_network *sipnet) |
| Check if network socket is open. | |
| GNURK int | sipsocket_open (struct sip_network *sipnet) |
| Open network socket, bind to address and set options (TOS). | |
| GNURK void | stop_media_flows (struct sip_dialog *dialog) |
| Immediately stop RTP, VRTP and UDPTL as applicable. | |
| GNURK const char * | subscription_type2str (enum subscriptiontype subtype) attribute_pure |
| Show subscription type in string format. | |
| GNURK struct sip_device * | temp_device (const char *name) |
| Create temporary peer (used in autocreatepeer mode). | |
| GNURK void | transmit_fake_auth_response (struct sip_dialog *p, struct sip_request *req, int reliable) |
| Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
| GNURK int | transmit_final_response (struct sip_dialog *dialog, const char *msg, struct sip_request *req, enum xmittype reliable) |
| Transmit final response to a request and close dialog Set dialog state to TERMINATED to avoid problems At some point, after debugging, we can remove the reliable flag. Only responses to INVITEs are sent reliably. | |
| GNURK int | transmit_info_with_digit (struct sip_dialog *p, const char digit, unsigned int duration) |
| Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
| GNURK int | transmit_info_with_vidupdate (struct sip_dialog *p) |
| Send SIP INFO with video update request. | |
| GNURK int | transmit_invite (struct sip_dialog *p, int sipmethod, int sdp, int init) |
| Build REFER/INVITE/OPTIONS message and transmit it. | |
| GNURK int | transmit_message_with_text (struct sip_dialog *p, const char *text) |
| Transmit text with SIP MESSAGE method. | |
| GNURK int | transmit_notify_with_mwi (struct sip_dialog *p, int newmsgs, int oldmsgs, char *vmexten) |
| Notify user of messages waiting in voicemail. | |
| GNURK int | transmit_notify_with_sipfrag (struct sip_dialog *p, int cseq, char *message, int terminate) |
| Notify a transferring party of the status of transfer. | |
| GNURK int | transmit_refer (struct sip_dialog *p, const char *dest) |
| Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
| GNURK int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
| Transmit register to SIP proxy or UA. | |
| GNURK int | transmit_reinvite_with_sdp (struct sip_dialog *p, int t38version) |
| Transmit reinvite with SDP. | |
| GNURK int | transmit_request (struct sip_dialog *p, int sipmethod, int inc, enum xmittype reliable, int newbranch) |
| Transmit generic SIP request. | |
| GNURK int | transmit_request_with_auth (struct sip_dialog *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
| Transmit SIP request, auth added. | |
| GNURK int | transmit_response (struct sip_dialog *p, const char *msg, struct sip_request *req) |
| Transmit response, no retransmits. | |
| GNURK int | transmit_response_reliable (struct sip_dialog *p, const char *msg, struct sip_request *req) |
| Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
| GNURK int | transmit_response_with_attachment (enum responseattach attach, struct sip_dialog *p, const char *msg, struct sip_request *req, enum xmittype reliable) |
| Transmit responses with various attachments. | |
| GNURK int | transmit_response_with_auth (struct sip_dialog *p, const char *msg, struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale) |
| Respond with authorization request. | |
| GNURK int | transmit_response_with_unsupported (struct sip_dialog *p, const char *msg, struct sip_request *req, const char *unsupported) |
| Transmit response, no retransmits. | |
| GNURK int | transmit_sip_request (struct sip_dialog *p, struct sip_request *req) |
| Transmit SIP request unreliably (only used in sip_notify subsystem). | |
| GNURK int | transmit_state_notify (struct sip_dialog *p, int state, int full, int timeout) |
| Used in the SUBSCRIBE notification subsystem. | |
| GNURK void | try_suggested_sip_codec (struct sip_dialog *p) |
| GNURK void | unregister_rtp_and_udptl (void) |
| UNRegister RTP and UDPTL to the subsystems. | |
| GNURK int | update_call_counter (struct sip_dialog *fup, int event) |
| update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
| GNURK void | update_peer (struct sip_device *device, int expiry) |
| Update peer data in database (if used). | |
Variables | |
| GNURK struct ast_custom_function | checksipdomain_function |
|
|
Definition at line 40 of file sip3funcs.h. |
|
||||||||||||||||
|
Definition at line 587 of file sip3_parse.c. References ast_log(), ast_test_flag, sip_request::header, sip_request::headers, len, LOG_ERROR, parse_request(), SIP_PKT_CONNECTED, and SIP_PKT_PARSED. 00588 { 00589 int pass; 00590 00591 if (!ast_test_flag(req, SIP_PKT_PARSED)) { 00592 /* Ok, so this req is not parse by parse_request yet. */ 00593 /* Parsing it before we have finished re-transmit may be bad. */ 00594 if (!ast_test_flag(req, SIP_PKT_CONNECTED)) 00595 parse_request(req); 00596 else { 00597 ast_log(LOG_ERROR, "Can't get header %s from request before parsing. Hang in for a jumpy ride!\n", name); 00598 return ""; 00599 } 00600 00601 } 00602 /* 00603 * Technically you can place arbitrary whitespace both before and after the ':' in 00604 * a header, although RFC3261 clearly says you shouldn't before, and place just 00605 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 00606 * a good idea to say you can do it, and if you can do it, why in the hell would. 00607 * you say you shouldn't. 00608 */ 00609 for (pass = 0; name && pass < 2;pass++) { 00610 int x, len = strlen(name); 00611 for (x=*start; x<req->headers; x++) { 00612 if (!strncasecmp(req->header[x], name, len)) { 00613 char *r = req->header[x] + len; /* skip name */ 00614 r = ast_skip_blanks(r); 00615 00616 if (*r == ':') { 00617 *start = x+1; 00618 return ast_skip_blanks(r+1); 00619 } 00620 } 00621 } 00622 if (pass == 0) /* Try aliases */ 00623 name = find_alias(name, NULL); 00624 } 00625 00626 /* Don't return NULL, so get_header is always a valid pointer */ 00627 return ""; 00628 }
|
|
||||||||||||||||||||||||
|
For a reliable transmission, we need to get an reply to stop retransmission. Acknowledges receipt of a packet and stops retransmission.
Definition at line 261 of file sip3_dialog.c. References ast_clear_flag, ast_log(), ast_sched_del(), ast_test_flag, sip_request::dialog, dialog_lock(), FALSE, LOG_DEBUG, sip_request::method, sip_request::next, option_debug, sip_dialog::packets, parse_request(), sip_dialog::pendinginvite, sip_request::retransid, sip_request::seqno, SIP_PKT_CONNECTED, SIP_PKT_INITREQ, SIP_PKT_PARSED, SIP_PKT_RESPONSE, sipdebug, siprequest_free(), TRUE, and UNLINK. 00262 { 00263 struct sip_request *cur, *prev = NULL; 00264 int res = FALSE; 00265 00266 if (option_debug) { 00267 if (!resp) 00268 ast_log(LOG_DEBUG, "Trying to confirm pending invite %d Call ID %s\n", dialog->pendinginvite, dialog->callid); 00269 else 00270 ast_log(LOG_DEBUG, "Trying to confirm pending response on Call ID %s\n", dialog->callid); 00271 } 00272 00273 dialog_lock(dialog, TRUE); 00274 00275 /* Find proper transaction */ 00276 for (cur = dialog->packets; cur; prev = cur, cur = cur->next) { 00277 if (option_debug > 2) 00278 ast_log(LOG_DEBUG, "--Checking packet with seqno %d against response with seqno %d\n", cur->seqno, seqno); 00279 /* Match on seqno AND req/resp AND method? */ 00280 if ((cur->seqno == seqno) && ((ast_test_flag(cur, SIP_PKT_RESPONSE)) == resp) && 00281 ((ast_test_flag(cur, SIP_PKT_RESPONSE)) || (cur->method == sipmethod))) { 00282 if (!resp && (seqno == dialog->pendinginvite)) { 00283 if (sipdebug && option_debug && !reset) 00284 ast_log(LOG_DEBUG, "Got reply to pending invite %d - Call Id %s\n", dialog->pendinginvite, dialog->callid); 00285 dialog->pendinginvite = 0; 00286 } else { 00287 if (sipdebug && option_debug && !reset) 00288 ast_log(LOG_DEBUG, "Got ACK on INVITE response Cseq %d Call Id %s\n", cur->seqno, dialog->callid); 00289 } 00290 /* this is our baby */ 00291 res = TRUE; 00292 UNLINK(cur, dialog->packets, prev); 00293 if (cur->retransid > -1) { 00294 if (sipdebug && option_debug > 3 && !reset) 00295 ast_log(LOG_DEBUG, "Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 00296 ast_sched_del(sched, cur->retransid); 00297 cur->retransid = -1; 00298 } 00299 if (!reset) { 00300 if (!ast_test_flag(cur, SIP_PKT_INITREQ)) 00301 siprequest_free(cur); /* We might want to keep this somewhere else */ 00302 else { 00303 if (sipdebug && option_debug > 3 && !reset) 00304 ast_log(LOG_DEBUG, "This is the initial request, keeping it in memory - Cseq %d\n", cur->seqno); 00305 ast_clear_flag(cur, SIP_PKT_CONNECTED); 00306 if (!ast_test_flag(cur, SIP_PKT_PARSED)) 00307 parse_request(cur); /* Parse initreq now, after we have answer */ 00308 } 00309 } 00310 break; 00311 } 00312 } 00313 dialog_lock(dialog, FALSE); 00314 if (option_debug && sipdebug) 00315 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", dialog->callid, resp ? "Response" : "Request", seqno, res ? "Found" : "Not Found"); 00316 }
|
|
||||||||||||||||
|
Execute destruction of SIP dialog structure, release memory.
Definition at line 366 of file sip3_dialog.c. References ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), AST_LIST_REMOVE_HEAD, ast_log(), ast_rtp_destroy(), ast_sched_del(), ast_test_flag, ast_udptl_destroy(), ast_verbose(), ASTOBJ_UNREF, DEC_CALL_LIMIT, DEC_CALL_RINGING, sip_request::dialog, dialoglist, dialoglist_lock(), sip_globals::dumphistory, sip_dialog::flags, free, free_old_route(), global, LOG_DEBUG, sip_dialog::next, option_debug, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_method2txt(), SIP_PAGE2_INC_RINGING, sip_registry_destroy(), UNLINK, and update_call_counter(). 00367 { 00368 struct sip_dialog *cur, *prev = NULL; 00369 struct sip_request *cp; 00370 00371 if (ast_test_flag(&dialog->flags[0], SIP_INC_COUNT)) /* This dialog has incremented call count */ 00372 update_call_counter(dialog, DEC_CALL_LIMIT); /* Since it was forgotten, decrement call count */ 00373 00374 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_INC_RINGING)) /* This dialog has incremented ring count */ 00375 update_call_counter(dialog, DEC_CALL_RINGING); /* Since it was forgotten, decrement ring count */ 00376 00377 if (sip_debug_test_pvt(dialog) || option_debug > 2) 00378 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", dialog->callid, sip_method2txt(dialog->method)); 00379 00380 00381 /* Remove link from peer to subscription of MWI */ 00382 if (dialog->relatedpeer && dialog->relatedpeer->mailbox.mwipvt) 00383 dialog->relatedpeer->mailbox.mwipvt = NULL; 00384 00385 if (global.dumphistory) 00386 sip_dump_history(dialog); 00387 00388 00389 if (dialog->stateid > -1) 00390 ast_extension_state_del(dialog->stateid, NULL); 00391 if (dialog->initid > -1) 00392 ast_sched_del(sched, dialog->initid); 00393 if (dialog->autokillid > -1) 00394 ast_sched_del(sched, dialog->autokillid); 00395 00396 if (dialog->inviteoptions) 00397 free(dialog->inviteoptions); 00398 00399 if (dialog->rtp) 00400 ast_rtp_destroy(dialog->rtp); 00401 if (dialog->vrtp) 00402 ast_rtp_destroy(dialog->vrtp); 00403 if (dialog->udptl) 00404 ast_udptl_destroy(dialog->udptl); 00405 if (dialog->refer) 00406 free(dialog->refer); 00407 if (dialog->route) { 00408 free_old_route(dialog->route); 00409 dialog->route = NULL; 00410 } 00411 if (dialog->registry) { 00412 if (dialog->registry->call == dialog) 00413 dialog->registry->call = NULL; 00414 ASTOBJ_UNREF(dialog->registry, sip_registry_destroy); 00415 } 00416 00417 /* Unlink us from the owner if we have one */ 00418 if (dialog->owner) { 00419 if (lockowner) 00420 ast_channel_lock(dialog->owner); 00421 if (option_debug) 00422 ast_log(LOG_DEBUG, "Detaching from %s\n", dialog->owner->name); 00423 dialog->owner->tech_pvt = NULL; 00424 if (lockowner) 00425 ast_channel_unlock(dialog->owner); 00426 } 00427 /* Clear history */ 00428 if (dialog->history) { 00429 struct sip_history *hist; 00430 while( (hist = AST_LIST_REMOVE_HEAD(dialog->history, list)) ) 00431 free(hist); 00432 free(dialog->history); 00433 dialog->history = NULL; 00434 } 00435 00436 00437 /* Unlink us from the dialog list */ 00438 if (lockdialoglist) 00439 dialoglist_lock(); 00440 for (prev = NULL, cur = dialoglist; cur; prev = cur, cur = cur->next) { 00441 if (cur == dialog) { 00442 UNLINK(cur, dialoglist, prev); 00443 break; 00444 } 00445 } 00446 if (lockdialoglist) 00447 dialoglist_unlock(); 00448 00449 if (!cur) { 00450 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", dialog->callid); 00451 return; 00452 } 00453 00454 /* remove all current packets in this dialog */ 00455 while((cp = dialog->packets)) { 00456 /* If one of the records in the packet list is the initreq, then release it */ 00457 if (cp == dialog->initreq) 00458 dialog->initreq = NULL; 00459 00460 dialog->packets = dialog->packets->next; 00461 if (cp->retransid > -1) 00462 ast_sched_del(sched, cp->retransid); 00463 free(cp); 00464 } 00465 00466 if (dialog->initreq) 00467 siprequest_free(dialog->initreq); 00468 00469 if (dialog->chanvars) { 00470 ast_variables_destroy(dialog->chanvars); 00471 dialog->chanvars = NULL; 00472 } 00473 ast_mutex_destroy(&dialog->lock); 00474 00475 ast_string_field_free_pools(dialog); 00476 00477 /* Finally, release the dialog */ 00478 free(dialog); 00479 00480 sipcounters.dialog_objects--; 00481 if (option_debug > 3) 00482 ast_log(LOG_DEBUG, "--DIALOGS-- Counter %d\n", sipcounters.dialog_objects); 00483 }
|
|
|
Pretend to ack all packets - nothing to do with SIP_ACK (the method) maybe the lock on p is not strictly necessary but there might be a race.
Definition at line 320 of file sip3_dialog.c. References __sip_ack(), ast_log(), ast_test_flag, sip_request::data, sip_request::dialog, FALSE, find_sip_method(), LOG_WARNING, sip_request::method, sip_dialog::packets, sip_request::seqno, sip_method2txt(), and SIP_PKT_RESPONSE. 00321 { 00322 struct sip_request *cur = NULL; 00323 00324 while (dialog->packets) { 00325 int method; 00326 if (cur == dialog->packets) { 00327 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_method2txt(cur->method)); 00328 return; 00329 } 00330 cur = dialog->packets; 00331 method = (cur->method) ? cur->method : find_sip_method(cur->data); 00332 __sip_ack(dialog, cur->seqno, ast_test_flag(cur, SIP_PKT_RESPONSE), method, FALSE); 00333 } 00334 }
|
|
||||||||||||||||||||
|
Acks receipt of packet, keep it around (used for provisional responses).
Definition at line 339 of file sip3_dialog.c. References ast_log(), ast_sched_del(), ast_test_flag, sip_request::data, sip_request::dialog, LOG_DEBUG, method_match(), sip_request::next, option_debug, sip_dialog::packets, sip_request::retransid, sip_request::seqno, sip_method2txt(), SIP_PKT_RESPONSE, and sipdebug. 00340 { 00341 struct sip_request *cur; 00342 int res = -1; 00343 00344 for (cur = dialog->packets; cur; cur = cur->next) { 00345 if (option_debug > 2) 00346 ast_log(LOG_DEBUG, "--Checking packet with seqno %d against response with seqno %d\n", cur->seqno, seqno); 00347 if (cur->seqno == seqno && ast_test_flag(cur, SIP_PKT_RESPONSE) == resp && 00348 (ast_test_flag(cur, SIP_PKT_RESPONSE) || method_match(sipmethod, cur->data))) { 00349 /* this is our baby */ 00350 if (cur->retransid > -1) { 00351 if (option_debug > 3 && sipdebug) 00352 ast_log(LOG_DEBUG, "Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_method2txt(sipmethod)); 00353 ast_sched_del(sched, cur->retransid); 00354 } 00355 cur->retransid = -1; 00356 res = 0; 00357 break; 00358 } 00359 } 00360 if (option_debug) 00361 ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", dialog->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 00362 return res; 00363 }
|
|
||||||||||||||||||||
|
Base transmit response function. Definition at line 113 of file sip3_transmit.c. References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), sip_request::data_size, get_header(), ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, sip_dialog::method, sip_dialog::owner, respprep(), send_response(), sip_request::seqno, SIP_INVITE, SIP_MAX_PACKET, sipnet, siprequest_alloc(), siprequest_free(), and XMIT_UNRELIABLE. 00114 { 00115 struct sip_request *resp; 00116 int seqno = 0; 00117 int res; 00118 00119 00120 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 00121 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 00122 return -1; 00123 } 00124 00125 resp = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00126 ast_log(LOG_DEBUG, " :::: Response data size: %d\n", (int) resp->data_size); 00127 resp->seqno = seqno; 00128 respprep(resp, p, msg, req); 00129 add_header_contentLength(resp, 0); 00130 /* If we are cancelling an incoming invite for some reason, add information 00131 about the reason why we are doing this in clear text */ 00132 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 00133 char buf[10]; 00134 00135 add_header(resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 00136 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 00137 add_header(resp, "X-Asterisk-HangupCauseCode", buf); 00138 } 00139 res = send_response(p, resp, reliable); 00140 if (reliable == XMIT_UNRELIABLE) 00141 siprequest_free(resp); 00142 return res; 00143 }
|
|
|
add a blank line if no body
Definition at line 128 of file sip3_compose.c. References sip_request::data, sip_request::data_size, sip_request::len, and sip_request::lines. 00129 { 00130 if (!req->lines) { 00131 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 00132 snprintf(req->data + req->len, req->data_size - req->len, "\r\n"); 00133 req->len += strlen(req->data + req->len); 00134 } 00135 }
|
|
||||||||||||||||
|
Add DTMF INFO tone to sip message.
Definition at line 205 of file sip3_compose.c. References add_header(), add_header_contentLength(), and add_line(). 00206 { 00207 char tmp[256]; 00208 00209 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 00210 add_header(req, "Content-Type", "application/dtmf-relay"); 00211 add_header_contentLength(req, strlen(tmp)); 00212 add_line(req, tmp); 00213 return 0; 00214 }
|
|
||||||||||||||||
|
Add header to SIP message. sip3_compose.c : Composing new SIP messages Definition at line 89 of file sip3_compose.c. References ast_log(), sip_globals::compactheaders, sip_request::data, sip_request::data_size, find_alias(), global, sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_DEBUG, LOG_WARNING, option_debug, and SIP_MAX_HEADERS. 00090 { 00091 int maxlen = req->data_size - 4 - req->len; /* 4 bytes are for two \r\n ? */ 00092 00093 if (req->headers == SIP_MAX_HEADERS) { 00094 ast_log(LOG_WARNING, "Out of SIP header space\n"); 00095 return -1; 00096 } 00097 00098 if (req->lines) { 00099 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 00100 return -1; 00101 } 00102 00103 if (maxlen <= 0) { 00104 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 00105 if (option_debug > 2) 00106 ast_log(LOG_DEBUG, " ==== Req->len %d, req->data size %d Maxlen %d\n", req->len, (int) req->data_size, maxlen); 00107 return -1; 00108 } 00109 00110 req->header[req->headers] = req->data + req->len; 00111 00112 if (global.compactheaders) 00113 var = find_alias(var, var); 00114 00115 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 00116 req->len += strlen(req->header[req->headers]); 00117 req->headers++; 00118 if (req->headers < SIP_MAX_HEADERS) 00119 req->headers++; 00120 else 00121 ast_log(LOG_WARNING, "Out of SIP header space... Will generate broken SIP message\n"); 00122 00123 return 0; 00124 }
|
|
||||||||||||
|
Add 'Content-Length' header to SIP message.
Definition at line 362 of file sip3_compose.c. References add_header(). 00363 { 00364 char clen[10]; 00365 00366 snprintf(clen, sizeof(clen), "%d", len); 00367 return add_header(req, "Content-Length", clen); 00368 }
|
|
||||||||||||
|
Add content (not header) to SIP message.
Definition at line 399 of file sip3_compose.c. References ast_log(), sip_request::data, sip_request::data_size, sip_request::len, sip_request::line, sip_request::lines, LOG_WARNING, and SIP_MAX_LINES. 00400 { 00401 if (req->lines == SIP_MAX_LINES) { 00402 ast_log(LOG_WARNING, "Out of SIP line space\n"); 00403 return -1; 00404 } 00405 if (!req->lines) { 00406 /* Add extra empty return */ 00407 snprintf(req->data + req->len, req->data_size - req->len, "\r\n"); 00408 req->len += strlen(req->data + req->len); 00409 } 00410 if (req->len >= req->data_size - 4) { 00411 ast_log(LOG_WARNING, "Out of space, can't add anymore: Len %d Data %dd\n", req->len, (int) req->data_size); 00412 return -1; 00413 } 00414 req->line[req->lines] = req->data + req->len; 00415 snprintf(req->line[req->lines], req->data_size - req->len, "%s", line); 00416 req->len += strlen(req->line[req->lines]); 00417 req->lines++; 00418 return 0; 00419 }
|
|
||||||||||||||||
|
Add realm authentication in list.
Definition at line 495 of file sip3_auth.c. References ast_calloc, ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_auth::next, option_debug, option_verbose, sip_auth::realm, secret, strsep(), and sip_auth::username. 00496 { 00497 char authcopy[256]; 00498 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 00499 char *stringp; 00500 struct sip_auth *a, *b, *auth; 00501 00502 if (ast_strlen_zero(configuration)) 00503 return authlist; 00504 00505 if (option_debug) 00506 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 00507 00508 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 00509 stringp = authcopy; 00510 00511 username = stringp; 00512 realm = strrchr(stringp, '@'); 00513 if (realm) 00514 *realm++ = '\0'; 00515 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 00516 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 00517 return authlist; 00518 } 00519 stringp = username; 00520 username = strsep(&stringp, ":"); 00521 if (username) { 00522 secret = strsep(&stringp, ":"); 00523 if (!secret) { 00524 stringp = username; 00525 md5secret = strsep(&stringp,"#"); 00526 } 00527 } 00528 if (!(auth = ast_calloc(1, sizeof(*auth)))) 00529 return authlist; 00530 00531 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 00532 ast_copy_string(auth->username, username, sizeof(auth->username)); 00533 if (secret) 00534 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 00535 if (md5secret) 00536 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 00537 00538 /* find the end of the list */ 00539 for (b = NULL, a = authlist; a ; b = a, a = a->next) 00540 ; 00541 if (b) 00542 b->next = auth; /* Add structure add end of list */ 00543 else 00544 authlist = auth; 00545 00546 if (option_verbose > 2) 00547 ast_verbose("Added authentication for realm %s\n", realm); 00548 00549 return authlist; 00550 00551 }
|
|
||||||||||||
|
Add route header into request per learned route.
Definition at line 371 of file sip3_compose.c. References sip_route::hop, and sip_route::next. 00372 { 00373 char r[BUFSIZ*2], *p; 00374 int n, rem = sizeof(r); 00375 00376 if (!route) 00377 return; 00378 00379 p = r; 00380 for (;route ; route = route->next) { 00381 n = strlen(route->hop); 00382 if (rem < n+3) /* we need room for ",<route>" */ 00383 break; 00384 if (p != r) { /* add a separator after fist route */ 00385 *p++ = ','; 00386 --rem; 00387 } 00388 *p++ = '<'; 00389 ast_copy_string(p, route->hop, rem); /* cannot fail */ 00390 p += n; 00391 *p++ = '>'; 00392 rem -= (n+2); 00393 } 00394 *p = '\0'; 00395 add_header(req, "Route", r); 00396 }
|
|
||||||||||||
|
Add Session Description Protocol message.
Definition at line 1029 of file sip3_sdprtp.c. References add_codec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_test_flag, ast_verbose(), capability, FALSE, sip_dialog::flags, get_our_media_address(), sip_dialog::jointcapability, len, LOG_WARNING, sip_dialog::maxcallbitrate, option_debug, sip_dialog::ourip, sip_dialog::prefcodec, sip_dialog::prefs, sip_dialog::rtp, sip_dialog::sessionid, sip_dialog::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, sip_dialog::t38, t38properties::t38support, TRUE, and sip_dialog::vrtp. 01030 { 01031 int len = 0; 01032 int alreadysent = 0; 01033 01034 struct sockaddr_in sin; 01035 struct sockaddr_in vsin; 01036 struct sockaddr_in dest; 01037 struct sockaddr_in vdest = { 0, }; 01038 01039 /* SDP fields */ 01040 char *version = "v=0\r\n"; /* Protocol version */ 01041 char *subject = "s=session\r\n"; /* Subject of the session */ 01042 char owner[256]; /* Session owner/creator */ 01043 char connection[256]; /* Connection data */ 01044 char *stime = "t=0 0\r\n"; /* Time the session is active */ 01045 char bandwidth[256] = ""; /* Max bitrate */ 01046 char *hold; 01047 char m_audio[256]; /* Media declaration line for audio */ 01048 char m_video[256]; /* Media declaration line for video */ 01049 char a_audio[1024]; /* Attributes for audio */ 01050 char a_video[1024]; /* Attributes for video */ 01051 char *m_audio_next = m_audio; 01052 char *m_video_next = m_video; 01053 size_t m_audio_left = sizeof(m_audio); 01054 size_t m_video_left = sizeof(m_video); 01055 char *a_audio_next = a_audio; 01056 char *a_video_next = a_video; 01057 size_t a_audio_left = sizeof(a_audio); 01058 size_t a_video_left = sizeof(a_video); 01059 01060 int x; 01061 int capability; 01062 int needvideo = FALSE; 01063 int debug = sip_debug_test_pvt(p); 01064 int min_audio_packet_size = 0; 01065 int min_video_packet_size = 0; 01066 01067 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 01068 01069 if (!p->rtp) { 01070 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 01071 return -1; 01072 } 01073 01074 /* Set RTP Session ID and version */ 01075 if (!p->sessionid) { 01076 p->sessionid = getpid(); 01077 p->sessionversion = p->sessionid; 01078 } else 01079 p->sessionversion++; 01080 01081 /* Ok, let's start working with codec selection here */ 01082 capability = p->jointcapability; 01083 01084 if (option_debug > 1) { 01085 char codecbuf[BUFSIZ]; 01086 ast_log(LOG_DEBUG, "** Our capability: %s Video flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), ast_test_flag(&p->flags[0], SIP_NOVIDEO) ? "True" : "False"); 01087 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 01088 } 01089 01090 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 01091 if ((ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP))) { 01092 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 01093 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 01094 } 01095 #endif 01096 01097 /* Check if we need video in this call */ 01098 if((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 01099 if (p->vrtp) { 01100 needvideo = TRUE; 01101 if (option_debug > 1) 01102 ast_log(LOG_DEBUG, "This call needs video offers! \n"); 01103 } else if (option_debug > 1) 01104 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled ! \n"); 01105 } 01106 01107 /* Get our media IP addresses for RTP */ 01108 get_our_media_address(p, needvideo, &sin, &vsin, &dest, &vdest); 01109 01110 /* Ok, we need video. Let's add what we need for video and set codecs. 01111 Video is handled differently than audio since we can not transcode. */ 01112 if (needvideo) { 01113 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 01114 01115 /* Build max bitrate string */ 01116 if (p->maxcallbitrate) 01117 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 01118 if (debug) 01119 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 01120 01121 /*! \todo XXX We need to select one codec, not many, since there's no transcoding */ 01122 } 01123 if (debug) 01124 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 01125 01126 /* Start building generic SDP headers */ 01127 01128 /* We break with the "recommendation" and send our IP, in order that our 01129 peer doesn't have to ast_gethostbyname() us */ 01130 01131 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 01132 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 01133 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 01134 01135 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR)) 01136 hold = "a=recvonly\r\n"; 01137 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE)) 01138 hold = "a=inactive\r\n"; 01139 else 01140 hold = "a=sendrecv\r\n"; 01141 01142 /* Now, start adding audio codecs. These are added in this order: 01143 - First what was requested by the calling channel 01144 - Then preferences in order from sip.conf device config for this peer/user 01145 - Then other codecs in capabilities, including video 01146 */ 01147 01148 /* Prefer the audio codec we were requested to use, first, no matter what 01149 Note that p->prefcodec can include video codecs, so mask them out 01150 */ 01151 if (capability & p->prefcodec) { 01152 add_codec_to_sdp(p, p->prefcodec & AST_FORMAT_AUDIO_MASK, 8000, 01153 &m_audio_next, &m_audio_left, 01154 &a_audio_next, &a_audio_left, 01155 debug, &min_audio_packet_size); 01156 alreadysent |= p->prefcodec & AST_FORMAT_AUDIO_MASK; 01157 } 01158 01159 01160 /* Start by sending our preferred audio codecs */ 01161 for (x = 0; x < 32; x++) { 01162 int pref_codec; 01163 01164 if (!(pref_codec = ast_codec_pref_index(&p->prefs, x))) 01165 break; 01166 01167 if (!(capability & pref_codec)) 01168 continue; 01169 01170 if (alreadysent & pref_codec) 01171 continue; 01172 01173 add_codec_to_sdp(p, pref_codec, 8000, 01174 &m_audio_next, &m_audio_left, 01175 &a_audio_next, &a_audio_left, 01176 debug, &min_audio_packet_size); 01177 alreadysent |= pref_codec; 01178 } 01179 01180 /* Now send any other common audio and video codecs, and non-codec formats: */ 01181 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 01182 if (!(capability & x)) /* Codec not requested */ 01183 continue; 01184 01185 if (alreadysent & x) /* Already added to SDP */ 01186 continue; 01187 01188 if (x <= AST_FORMAT_MAX_AUDIO) 01189 add_codec_to_sdp(p, x, 8000, 01190 &m_audio_next, &m_audio_left, 01191 &a_audio_next, &a_audio_left, 01192 debug, &min_audio_packet_size); 01193 else 01194 add_codec_to_sdp(p, x, 90000, 01195 &m_video_next, &m_video_left, 01196 &a_video_next, &a_video_left, 01197 debug, &min_video_packet_size); 01198 } 01199 01200 /* Now add DTMF RFC2833 telephony-event as a codec */ 01201 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 01202 if (!(p->jointnoncodeccapability & x)) 01203 continue; 01204 01205 add_noncodec_to_sdp(p, x, 8000, 01206 &m_audio_next, &m_audio_left, 01207 &a_audio_next, &a_audio_left, 01208 debug); 01209 } 01210 01211 if (option_debug > 2) 01212 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 01213 01214 if(!p->owner || !ast_internal_timing_enabled(p->owner)) 01215 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 01216 if (min_audio_packet_size) 01217 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 01218 01219 if (min_video_packet_size) 01220 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 01221 01222 01223 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 01224 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 01225 01226 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 01227 if (needvideo) 01228 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 01229 01230 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 01231 if (needvideo) /* only if video response is appropriate */ 01232 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 01233 01234 add_header(resp, "Content-Type", "application/sdp"); 01235 add_header_contentLength(resp, len); 01236 add_line(resp, version); 01237 add_line(resp, owner); 01238 add_line(resp, subject); 01239 add_line(resp, connection); 01240 if (needvideo) /* only if video response is appropriate */ 01241 add_line(resp, bandwidth); 01242 add_line(resp, stime); 01243 add_line(resp, m_audio); 01244 add_line(resp, a_audio); 01245 add_line(resp, hold); 01246 if (needvideo) { /* only if video response is appropriate */ 01247 add_line(resp, m_video); 01248 add_line(resp, a_video); 01249 add_line(resp, hold); /* Repeat hold for the video stream */ 01250 } 01251 01252 /* Update lastrtprx when we send our SDP */ 01253 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 01254 01255 if (option_debug > 2) { 01256 char buf[BUFSIZ]; 01257 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, BUFSIZ, capability)); 01258 } 01259 01260 return 0; 01261 }
|
|
||||||||||||||||
|
Add SIP domain to list of domains we are responsible for. sip3_domain.c: Domain handling functions (sip domain hosting, not DNS lookups) Definition at line 95 of file sip3_domain.c. References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), LOG_DEBUG, LOG_WARNING, and option_debug. 00096 { 00097 struct domain *d; 00098 00099 if (ast_strlen_zero(domain)) { 00100 ast_log(LOG_WARNING, "Zero length domain.\n"); 00101 return 1; 00102 } 00103 00104 if (!(d = ast_calloc(1, sizeof(*d)))) 00105 return 0; 00106 00107 ast_copy_string(d->domain, domain, sizeof(d->domain)); 00108 00109 if (!ast_strlen_zero(context)) 00110 ast_copy_string(d->context, context, sizeof(d->context)); 00111 00112 d->mode = mode; 00113 00114 AST_LIST_LOCK(&domain_list); 00115 AST_LIST_INSERT_TAIL(&domain_list, d, list); 00116 AST_LIST_UNLOCK(&domain_list); 00117 00118 if (option_debug > 2) 00119 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 00120 00121 return 1; 00122 }
|
|
||||||||||||
|
Add T.38 Session Description Protocol message.
Definition at line 1749 of file chan_sip3.c. References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), t38properties::capability, debug(), t38properties::jointcapability, sip_dialog::lastrtprx, sip_dialog::lastrtptx, len, LOG_DEBUG, LOG_WARNING, sip_dialog::ourip, t38properties::peercapability, s, sip_dialog::sessionid, sip_dialog::sessionversion, sip_debug_test_pvt(), sip_dialog::t38, t38_get_rate(), T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION, T38FAX_VERSION_0, T38FAX_VERSION_1, sip_dialog::udptl, and sip_dialog::udptlredirip. 01750 { 01751 int len = 0; 01752 int x = 0; 01753 struct sockaddr_in udptlsin; 01754 char v[256] = ""; 01755 char s[256] = ""; 01756 char o[256] = ""; 01757 char c[256] = ""; 01758 char t[256] = ""; 01759 char m_modem[256]; 01760 char a_modem[1024]; 01761 char *m_modem_next = m_modem; 01762 size_t m_modem_left = sizeof(m_modem); 01763 char *a_modem_next = a_modem; 01764 size_t a_modem_left = sizeof(a_modem); 01765 struct sockaddr_in udptldest = { 0, }; 01766 int debug; 01767 01768 debug = sip_debug_test_pvt(p); 01769 len = 0; 01770 if (!p->udptl) { 01771 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 01772 return -1; 01773 } 01774 01775 if (!p->sessionid) { 01776 p->sessionid = getpid(); 01777 p->sessionversion = p->sessionid; 01778 } else 01779 p->sessionversion++; 01780 01781 /* Our T.38 end is */ 01782 ast_udptl_get_us(p->udptl, &udptlsin); 01783 01784 /* Determine T.38 UDPTL destination */ 01785 if (p->udptlredirip.sin_addr.s_addr) { 01786 udptldest.sin_port = p->udptlredirip.sin_port; 01787 udptldest.sin_addr = p->udptlredirip.sin_addr; 01788 } else { 01789 udptldest.sin_addr = p->ourip; 01790 udptldest.sin_port = udptlsin.sin_port; 01791 } 01792 01793 if (debug) 01794 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 01795 01796 /* We break with the "recommendation" and send our IP, in order that our 01797 peer doesn't have to ast_gethostbyname() us */ 01798 01799 if (debug) { 01800 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 01801 p->t38.capability, 01802 p->t38.peercapability, 01803 p->t38.jointcapability); 01804 } 01805 snprintf(v, sizeof(v), "v=0\r\n"); 01806 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 01807 snprintf(s, sizeof(s), "s=session\r\n"); 01808 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 01809 snprintf(t, sizeof(t), "t=0 0\r\n"); 01810 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 01811 01812 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 01813 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 01814 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 01815 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 01816 if ((x = t38_get_rate(p->t38.jointcapability))) 01817 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 01818 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 01819 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 01820 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 01821 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 01822 x = ast_udptl_get_local_max_datagram(p->udptl); 01823 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 01824 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 01825 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 01826 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 01827 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 01828 add_header(resp, "Content-Type", "application/sdp"); 01829 add_header_contentLength(resp, len); 01830 add_line(resp, v); 01831 add_line(resp, o); 01832 add_line(resp, s); 01833 add_line(resp, c); 01834 add_line(resp, t); 01835 add_line(resp, m_modem); 01836 add_line(resp, a_modem); 01837 01838 /* Update lastrtprx when we send our SDP */ 01839 p->lastrtprx = p->lastrtptx = time(NULL); 01840 01841 return 0; 01842 }
|
|
||||||||||||
|
Add text body to SIP message.
Definition at line 195 of file sip3_compose.c. References add_header(), add_header_contentLength(), and add_line(). 00196 { 00197 /* XXX Convert \n's to \r\n's XXX */ 00198 add_header(req, "Content-Type", "text/plain"); 00199 add_header_contentLength(req, strlen(text)); 00200 add_line(req, text); 00201 return 0; 00202 }
|
|
|
Append date to SIP message.
Definition at line 175 of file sip3_compose.c. References add_header(). 00176 { 00177 char tmpdat[256]; 00178 struct tm tm; 00179 time_t t = time(NULL); 00180 00181 gmtime_r(&t, &tm); 00182 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 00183 add_header(req, "Date", tmpdat); 00184 }
|
|
||||||||||||||||
|
Append to SIP dialog history with arg list.
Definition at line 127 of file sip3_utils.c. References append_history_va(). 00128 { 00129 va_list ap; 00130 00131 if (!dialog) 00132 return; 00133 va_start(ap, fmt); 00134 append_history_va(dialog, fmt, ap); 00135 va_end(ap); 00136 00137 return; 00138 }
|
|
||||||||||||||||
|
Append to SIP dialog history with arg list.
Definition at line 107 of file sip3_utils.c. References ast_calloc, AST_LIST_INSERT_TAIL, free, and strsep(). 00108 { 00109 char buf[80], *c = buf; /* max history length */ 00110 struct sip_history *hist; 00111 int l; 00112 00113 vsnprintf(buf, sizeof(buf), fmt, ap); 00114 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 00115 l = strlen(buf) + 1; 00116 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 00117 return; 00118 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 00119 free(hist); 00120 return; 00121 } 00122 memcpy(hist->event, buf, l); 00123 AST_LIST_INSERT_TAIL(p->history, hist, list); 00124 }
|
|
|
Append Max-Forwards header to request.
Definition at line 187 of file sip3_compose.c. References add_header(), global, and sip_globals::maxforwards. Referenced by reqprep(), transmit_refer(), and transmit_register(). 00188 { 00189 char buf[4]; 00190 snprintf(buf, sizeof(buf), "%d", global.maxforwards); 00191 add_header(req, "Max-Forwards", buf); 00192 }
|
|
|
Turn off generator data XXX Does this function belong in the SIP channel?
Definition at line 4034 of file chan_sip3.c. References ast_channel::_state, ast_deactivate_generator(), AST_STATE_UP, and ast_channel::generatordata. 04035 { 04036 if (chan && chan->_state == AST_STATE_UP) { 04037 if (chan->generatordata) 04038 ast_deactivate_generator(chan); 04039 } 04040 }
|
|
||||||||||||||||
|
return the request and response heade for a 401 or 407 code Definition at line 133 of file sip3_auth.c. References ast_verbose(), PROXY_AUTH, and WWW_AUTH. 00134 { 00135 if (code == WWW_AUTH) { /* 401 */ 00136 *header = "WWW-Authenticate"; 00137 *respheader = "Authorization"; 00138 } else if (code == PROXY_AUTH) { /* 407 */ 00139 *header = "Proxy-Authenticate"; 00140 *respheader = "Proxy-Authorization"; 00141 } else { 00142 ast_verbose("-- wrong response code %d\n", code); 00143 *header = *respheader = "Invalid"; 00144 } 00145 }
|
|
|
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 164 of file sip3_compose.c. References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), sip_dialog::ourip, and S_OR. 00165 { 00166 char buf[33]; 00167 00168 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 00169 00170 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 00171 00172 }
|
|
|
Build contact header - the contact header we send out.
Definition at line 217 of file sip3_compose.c. References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), sipnet, sipnet_ourport(), and STANDARD_SIP_PORT. 00218 { 00219 /* Construct Contact: header */ 00220 if (sipnet_ourport(&sipnet) != STANDARD_SIP_PORT) /* Needs to be 5060, according to the RFC */ 00221 ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip), sipnet_ourport(&sipnet)); 00222 else 00223 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 00224 }
|
|
||||||||||||||||||||
|
Build reply digest.
Definition at line 428 of file sip3_auth.c. References ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, find_realm_authentication(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_dialog::noncecount, sip_dialog::sa, sip_auth::secret, secret, sip_method2txt(), and sip_auth::username. 00429 { 00430 char a1[256]; 00431 char a2[256]; 00432 char a1_hash[256]; 00433 char a2_hash[256]; 00434 char resp[256]; 00435 char resp_hash[256]; 00436 char uri[256]; 00437 char cnonce[80]; 00438 const char *username; 00439 const char *secret; 00440 const char *md5secret; 00441 struct sip_auth *auth = NULL; /* Realm authentication */ 00442 00443 if (!ast_strlen_zero(p->domain)) 00444 ast_copy_string(uri, p->domain, sizeof(uri)); 00445 else if (!ast_strlen_zero(p->uri)) 00446 ast_copy_string(uri, p->uri, sizeof(uri)); 00447 else 00448 snprintf(uri, sizeof(uri), "sip:%s@%s",p->peername, ast_inet_ntoa(p->sa.sin_addr)); 00449 00450 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 00451 00452 /* Check if we have separate auth credentials */ 00453 if ((auth = find_realm_authentication(authl, p->realm))) { 00454 ast_log(LOG_WARNING, "use realm [%s] from peer [%s]\n", 00455 auth->username, p->peername); 00456 username = auth->username; 00457 secret = auth->secret; 00458 md5secret = auth->md5secret; 00459 if (sipdebug) 00460 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 00461 } else { 00462 /* No authentication, use peer or register= config */ 00463 username = p->authname; 00464 secret = p->peersecret; 00465 md5secret = p->peermd5secret; 00466 } 00467 if (ast_strlen_zero(username)) /* We have no authentication */ 00468 return -1; 00469 00470 /* Calculate SIP digest response */ 00471 snprintf(a1,sizeof(a1), "%s:%s:%s", username, p->realm, secret); 00472 snprintf(a2,sizeof(a2), "%s:%s", sip_method2txt(method), uri); 00473 if (!ast_strlen_zero(md5secret)) 00474 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 00475 else 00476 ast_md5_hash(a1_hash, a1); 00477 ast_md5_hash(a2_hash,a2); 00478 00479 p->noncecount++; 00480 if (!ast_strlen_zero(p->qop)) 00481 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 00482 else 00483 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 00484 ast_md5_hash(resp_hash, resp); 00485 /* XXX We hard code our qop to "auth" for now. XXX */ 00486 if (!ast_strlen_zero(p->qop)) 00487 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\", qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, p->opaque, cnonce, p->noncecount); 00488 else 00489 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\"", username, p->realm, uri, p->nonce, resp_hash, p->opaque); 00490 00491 return 0; 00492 }
|
|
|
Build the Remote Party-ID & From using callingpres options.
Definition at line 228 of file sip3_compose.c. References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), sip_dialog::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, sip_globals::default_callerid, FALSE, global, LOG_WARNING, sip_dialog::ourip, sip_dialog::owner, S_OR, sip_dialog::tag, and TRUE. 00229 { 00230 int send_pres_tags = TRUE; 00231 const char *privacy=NULL; 00232 const char *screen=NULL; 00233 char buf[256]; 00234 const char *clid = global.default_callerid; 00235 const char *clin = NULL; 00236 const char *fromdomain; 00237 00238 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 00239 return; 00240 00241 if (p->owner && p->owner->cid.cid_num) 00242 clid = p->owner->cid.cid_num; 00243 if (p->owner && p->owner->cid.cid_name) 00244 clin = p->owner->cid.cid_name; 00245 if (ast_strlen_zero(clin)) 00246 clin = clid; 00247 00248 switch (p->callingpres) { 00249 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 00250 privacy = "off"; 00251 screen = "no"; 00252 break; 00253 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 00254 privacy = "off"; 00255 screen = "pass"; 00256 break; 00257 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 00258 privacy = "off"; 00259 screen = "fail"; 00260 break; 00261 case AST_PRES_ALLOWED_NETWORK_NUMBER: 00262 privacy = "off"; 00263 screen = "yes"; 00264 break; 00265 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 00266 privacy = "full"; 00267 screen = "no"; 00268 break; 00269 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 00270 privacy = "full"; 00271 screen = "pass"; 00272 break; 00273 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 00274 privacy = "full"; 00275 screen = "fail"; 00276 break; 00277 case AST_PRES_PROHIB_NETWORK_NUMBER: 00278 privacy = "full"; 00279 screen = "pass"; 00280 break; 00281 case AST_PRES_NUMBER_NOT_AVAILABLE: 00282 send_pres_tags = FALSE; 00283 break; 00284 default: 00285 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 00286 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 00287 privacy = "full"; 00288 else 00289 privacy = "off"; 00290 screen = "no"; 00291 break; 00292 } 00293 00294 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 00295 00296 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 00297 if (send_pres_tags) 00298 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 00299 ast_string_field_set(p, rpid, buf); 00300 00301 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 00302 S_OR(p->fromuser, clid), 00303 fromdomain, p->tag); 00304 }
|
|
||||||||||||
|
Build a Via header for a request.
Definition at line 1236 of file sip3_dialog.c. References ast_inet_ntoa(), ast_string_field_build, ast_test_flag, sip_dialog::flags, ourdialogbranch(), sip_dialog::ourip, SIP_NAT, SIP_NAT_RFC3581, sipnet, and sipnet_ourport(). 01237 { 01238 /* Work around buggy UNIDEN UIP200 firmware */ 01239 const char *rport = ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01240 01241 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01242 ast_string_field_build(dialog, via, "SIP/2.0/UDP %s:%d;branch=%s%s", 01243 ast_inet_ntoa(dialog->ourip), sipnet_ourport(&sipnet), 01244 ourdialogbranch(dialog, forcenewbranch), rport); 01245 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
Definition at line 152 of file sip3_auth.c. References ast_random(), ast_string_field_build, ast_strlen_zero(), AUTH_CHALLENGE_SENT, auth_headers(), AUTH_SUCCESSFUL, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), key(), keys, s, sip_scheddestroy(), strsep(), transmit_response_with_auth(), and WWW_AUTH. 00155 { 00156 const char *response = "407 Proxy Authentication Required"; 00157 char *reqheader; 00158 char *respheader; 00159 const char *authtoken; 00160 char a1_hash[256]; 00161 char resp_hash[256]=""; 00162 char tmp[BUFSIZ * 2]; /* Make a large enough buffer */ 00163 char *c; 00164 int wrongnonce = FALSE; 00165 int good_response; 00166 const char *usednonce = p->randdata; 00167 00168 /* table of recognised keywords, and their value in the digest */ 00169 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 00170 struct x { 00171 const char *key; 00172 const char *s; 00173 } *i, keys[] = { 00174 [K_RESP] = { "response=", "" }, 00175 [K_URI] = { "uri=", "" }, 00176 [K_USER] = { "username=", "" }, 00177 [K_NONCE] = { "nonce=", "" }, 00178 [K_LAST] = { NULL, NULL} 00179 }; 00180 00181 /* Always OK if no secret */ 00182 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 00183 return AUTH_SUCCESSFUL; 00184 response = "401 Unauthorized"; 00185 auth_headers(WWW_AUTH, &respheader, &reqheader); 00186 authtoken = get_header(req, reqheader); 00187 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 00188 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 00189 information */ 00190 if (!reliable) { 00191 /* Resend message if this was NOT a reliable delivery. Otherwise the 00192 retransmission should get it */ 00193 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 00194 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 00195 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 00196 } 00197 return AUTH_CHALLENGE_SENT; 00198 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 00199 /* We have no auth, so issue challenge and request authentication */ 00200 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 00201 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 00202 /* Schedule auto destroy in 32 seconds */ 00203 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 00204 return AUTH_CHALLENGE_SENT; 00205 } 00206 00207 /* --- We have auth, so check it */ 00208 00209 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 00210 an example in the spec of just what it is you're doing a hash on. */ 00211 00212 00213 /* Make a copy of the response and parse it */ 00214 ast_copy_string(tmp, authtoken, sizeof(tmp)); 00215 c = tmp; 00216 00217 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 00218 for (i = keys; i->key != NULL; i++) { 00219 const char *separator = ","; /* default */ 00220 00221 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 00222 continue; 00223 /* Found. Skip keyword, take text in quotes or up to the separator. */ 00224 c += strlen(i->key); 00225 if (*c == '"') { /* in quotes. Skip first and look for last */ 00226 c++; 00227 separator = "\""; 00228 } 00229 i->s = c; 00230 strsep(&c, separator); 00231 break; 00232 } 00233 if (i->key == NULL) /* not found, jump after space or comma */ 00234 strsep(&c, " ,"); 00235 } 00236 00237 /* Verify that digest username matches the username we auth as */ 00238 if (strcmp(username, keys[K_USER].s)) { 00239 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 00240 username, keys[K_USER].s); 00241 /* Oops, we're trying something here */ 00242 return AUTH_USERNAME_MISMATCH; 00243 } 00244 00245 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 00246 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 00247 wrongnonce = TRUE; 00248 usednonce = keys[K_NONCE].s; 00249 } 00250 00251 if (!ast_strlen_zero(md5secret)) 00252 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 00253 else { 00254 char a1[256]; 00255 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global.realm, secret); 00256 ast_md5_hash(a1_hash, a1); 00257 } 00258 00259 /* compute the expected response to compare with what we received */ 00260 { 00261 char a2[256]; 00262 char a2_hash[256]; 00263 char resp[256]; 00264 00265 snprintf(a2, sizeof(a2), "%s:%s", sip_method2txt(sipmethod), S_OR(keys[K_URI].s, uri)); 00266 ast_md5_hash(a2_hash, a2); 00267 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 00268 ast_md5_hash(resp_hash, resp); 00269 } 00270 00271 good_response = keys[K_RESP].s && 00272 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 00273 if (wrongnonce) { 00274 ast_string_field_build(p, randdata, "%08lx", ast_random()); 00275 if (good_response) { 00276 if (sipdebug) 00277 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 00278 /* We got working auth token, based on stale nonce . */ 00279 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 1); 00280 } else { 00281 /* Everything was wrong, so give the device one more try with a new challenge */ 00282 if (sipdebug) 00283 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 00284 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 00285 } 00286 00287 /* Schedule auto destroy in 32 seconds */ 00288 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 00289 return AUTH_CHALLENGE_SENT; 00290 } 00291 if (good_response) 00292 return AUTH_SUCCESSFUL; 00293 00294 /* Ok, we have a bad username/secret pair */ 00295 /* Challenge again, and again, and again */ 00296 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 00297 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 00298 00299 return AUTH_CHALLENGE_SENT; 00300 }
|
|
||||||||||||||||
|
check_sip_domain: Check if domain part of uri is local to our server
Definition at line 132 of file sip3_domain.c. References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, and domain::domain. 00133 { 00134 struct domain *d; 00135 int result = 0; 00136 00137 AST_LIST_LOCK(&domain_list); 00138 AST_LIST_TRAVERSE(&domain_list, d, list) { 00139 if (strcasecmp(d->domain, domain)) 00140 continue; 00141 00142 if (len && !ast_strlen_zero(d->context)) 00143 ast_copy_string(context, d->context, len); 00144 00145 result = 1; 00146 break; 00147 } 00148 AST_LIST_UNLOCK(&domain_list); 00149 00150 return result; 00151 }
|
|
|
Clear realm authentication list (at reload).
Definition at line 554 of file sip3_auth.c. References free, and sip_auth::next. 00555 { 00556 struct sip_auth *a = authlist; 00557 struct sip_auth *b; 00558 00559 while (a) { 00560 b = a; 00561 a = a->next; 00562 free(b); 00563 } 00564 00565 return 1; 00566 }
|
|
|
Clear our domain list (at reload).
Definition at line 154 of file sip3_domain.c. References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free. 00155 { 00156 struct domain *d; 00157 00158 AST_LIST_LOCK(&domain_list); 00159 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 00160 free(d); 00161 AST_LIST_UNLOCK(&domain_list); 00162 }
|
|
|
Close all open network sockets.
Definition at line 185 of file sip3_network.c. References sipnet, sip_network::sipsock, and TRUE.
|
|
||||||||||||||||
|
Do completion on peer name.
Definition at line 919 of file sip3_cliami.c. References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and devicelist. Referenced by complete_sip_debug_device(), complete_sip_prune_realtime_peer(), complete_sip_show_device(), and complete_sipnotify(). 00920 { 00921 char *result = NULL; 00922 int wordlen = strlen(word); 00923 int which = 0; 00924 00925 ASTOBJ_CONTAINER_TRAVERSE(&devicelist, !result, do { 00926 /* locking of the object is not required because only the name and flags are being compared */ 00927 if (!strncasecmp(word, iterator->name, wordlen) && 00928 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 00929 ++which > state) 00930 result = ast_strdup(iterator->name); 00931 } while(0) ); 00932 return result; 00933 }
|
|
||||||||||||||||||||
|
Support routine for 'sip show peer' CLI.
Definition at line 936 of file sip3_cliami.c. References complete_sip_device(). 00937 { 00938 if (pos == 3) 00939 return complete_sip_device(word, state, 0); 00940 00941 return NULL; 00942 }
|
|
||||||||||||||||
|
Copy all headers from one request to another.
Definition at line 649 of file sip3_parse.c. References __get_header(), add_header(), and ast_strlen_zero(). 00650 { 00651 int start = 0; 00652 int copied = 0; 00653 int res; 00654 00655 for (;;) { 00656 const char *tmp = __get_header(orig, field, &start); 00657 00658 if (ast_strlen_zero(tmp)) 00659 break; 00660 /* Add what we're responding to */ 00661 res = add_header(req, field, tmp); 00662 if (res != -1) 00663 copied++; 00664 else 00665 return -1; 00666 00667 } 00668 return copied ? 0 : -1; 00669 }
|
|
||||||||||||||||
|
Copy one header field from one request to another.
Definition at line 638 of file sip3_parse.c. References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE. 00639 { 00640 const char *tmp = get_header(orig, field); 00641 00642 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 00643 return add_header(req, field, tmp); 00644 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 00645 return -1; 00646 }
|
|
||||||||||||
|
copy SIP request (mostly used to save request for responses)
Definition at line 238 of file sip3_parse.c. References ast_calloc, ast_log(), free, LOG_DEBUG, offset, and option_debug. 00239 { 00240 long offset; 00241 int x; 00242 00243 offset = ((void *)dst) - ((void *)src); 00244 /* First copy stuff */ 00245 memcpy(dst, src, sizeof(*dst)); 00246 00247 /* Now, fix data part */ 00248 if (dst->data) 00249 free(dst->data); 00250 dst->data = ast_calloc(1, src->data_size); 00251 dst->data_size = src->data_size; 00252 memcpy(dst->data, src->data, src->data_size); 00253 00254 /* Now fix pointer arithmetic */ 00255 for (x=0; x < src->headers; x++) 00256 dst->header[x] += offset; 00257 for (x=0; x < src->lines; x++) 00258 dst->line[x] += offset; 00259 00260 if (option_debug > 3) 00261 ast_log(LOG_DEBUG, "==== Copied request... \n"); 00262 }
|
|
||||||||||||||||||||
|
Copy SIP VIA Headers from the request to the response.
Definition at line 677 of file sip3_parse.c. References __get_header(), add_header(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, sip_dialog::flags, sip_dialog::recv, SIP_NAT, SIP_NAT_ALWAYS, and SIP_NAT_RFC3581. 00678 { 00679 int copied = 0; 00680 int start = 0; 00681 00682 for (;;) { 00683 char new[256]; 00684 const char *oh = __get_header(orig, field, &start); 00685 00686 if (ast_strlen_zero(oh)) 00687 break; 00688 00689 if (!copied) { /* Only check for empty rport in topmost via header */ 00690 char leftmost[256], *others, *rport; 00691 00692 /* Only work on leftmost value */ 00693 ast_copy_string(leftmost, oh, sizeof(leftmost)); 00694 others = strchr(leftmost, ','); 00695 if (others) 00696 *others++ = '\0'; 00697 00698 /* Find ;rport; (empty request) */ 00699 rport = strstr(leftmost, ";rport"); 00700 if (rport && *(rport+6) == '=') 00701 rport = NULL; /* We already have a parameter to rport */ 00702 00703 if (rport && ( (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || 00704 (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581) ) ) { 00705 /* We need to add received port - rport */ 00706 char *end; 00707 00708 rport = strstr(leftmost, ";rport"); 00709 00710 if (rport) { 00711 end = strchr(rport + 1, ';'); 00712 if (end) 00713 memmove(rport, end, strlen(end) + 1); 00714 else 00715 *rport = '\0'; 00716 } 00717 00718 /* Add rport to first VIA header if requested */ 00719 /* Whoo hoo! Now we can indicate port address translation too! Just 00720 another RFC (RFC3581). I'll leave the original comments in for 00721 posterity. */ 00722 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 00723 leftmost, ast_inet_ntoa(p->recv.sin_addr), 00724 ntohs(p->recv.sin_port), 00725 others ? "," : "", others ? others : ""); 00726 } else { 00727 /* We should *always* add a received to the topmost via */ 00728 snprintf(new, sizeof(new), "%s;received=%s%s%s", 00729 leftmost, ast_inet_ntoa(p->recv.sin_addr), 00730 others ? "," : "", others ? others : ""); 00731 00732 } 00733 oh = new; /* the header to copy */ 00734 } /* else add the following via headers untouched */ 00735 add_header(req, field, oh); 00736 copied++; 00737 } 00738 if (!copied) { 00739 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 00740 return -1; 00741 } 00742 return 0; 00743 }
|
|
||||||||||||||||||||
|
create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
Definition at line 808 of file chan_sip3.c. References ahp, ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose(), create_addr_from_peer(), device_unref(), FALSE, find_device(), global, hp, LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, sip_dialog::recv, sip_dialog::sa, sip_globals::srvlookup, STANDARD_SIP_PORT, sip_globals::t1default, sip_dialog::timer_t1, and TRUE. 00809 { 00810 struct hostent *hp; 00811 struct ast_hostent ahp; 00812 struct sip_device *p = NULL; 00813 char *port; 00814 int portno; 00815 char host[MAXHOSTNAMELEN], *hostn; 00816 char peername[256]; 00817 char todomain[256]; 00818 int srvcheck = TRUE; 00819 00820 00821 dialog->sa.sin_family = AF_INET; 00822 dialog->timer_t1 = global.t1default; /* Default SIP retransmission timer T1 (RFC 3261) */ 00823 if (!ast_strlen_zero(device)) { 00824 int res; 00825 00826 p = find_device(device, NULL, 1); 00827 00828 if (p) { 00829 res = create_addr_from_peer(dialog, p); 00830 device_unref(p); 00831 return res; 00832 } else { 00833 if (option_verbose > 1) 00834 ast_verbose("Can't find peer %s\n", device); 00835 00836 return -1; /* Can't find peer */ 00837 } 00838 } 00839 00840 /* See if we have a port. If we have a given port, 00841 disable SRV lookups */ 00842 if (!ast_strlen_zero(domain)) { 00843 ast_copy_string(todomain, domain, sizeof(todomain)); 00844 port = strchr(todomain, ':'); 00845 } 00846 if (port) { 00847 *port++ = '\0'; 00848 srvcheck = FALSE; 00849 } 00850 00851 hostn = domain; 00852 portno = port ? atoi(port) : STANDARD_SIP_PORT; 00853 00854 if (global.srvlookup && srvcheck) { 00855 char service[MAXHOSTNAMELEN]; 00856 int tportno; 00857 int ret; 00858 00859 snprintf(service, sizeof(service), "_sip._udp.%s", domain); 00860 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 00861 if (ret > 0) { 00862 hostn = host; 00863 portno = tportno; 00864 if (option_debug > 2) 00865 ast_log(LOG_DEBUG, "Resolved domain %s to host %s in SRV \n", domain, hostn); 00866 } 00867 } 00868 hp = ast_gethostbyname(hostn, &ahp); 00869 if (!hp) { 00870 ast_log(LOG_WARNING, "No such host: %s\n", peername); 00871 return -2; 00872 } 00873 ast_string_field_set(dialog, tohost, domain); 00874 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 00875 dialog->sa.sin_port = htons(portno); 00876 dialog->recv = dialog->sa; 00877 return 0; 00878 }
|
|
|
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 380 of file sip3_objects.c. References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_device::flags, sip_globals::flags, global, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT. 00381 { 00382 if (!ast_test_flag(&global.flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 00383 if (ast_test_flag(&device->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 00384 ast_update_realtime("sippeers", "name", device->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "defaultuser", "", "regserver", "", NULL); 00385 else 00386 ast_db_del("SIP3-Registry", device->name); 00387 } 00388 }
|
|
|
Parse first line of incoming SIP request.
Definition at line 865 of file sip3_parse.c. References ast_log(), sip_request::header, LOG_WARNING, sip_request::rlPart1, and sip_request::rlPart2. 00866 { 00867 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 00868 00869 if (!*e) 00870 return -1; 00871 req->rlPart1 = e; /* method or protocol */ 00872 e = ast_skip_nonblanks(e); 00873 if (*e) 00874 *e++ = '\0'; 00875 /* Get URI or status code */ 00876 e = ast_skip_blanks(e); 00877 if ( !*e ) 00878 return -1; 00879 ast_trim_blanks(e); 00880 00881 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 00882 if (strlen(e) < 3) /* status code is 3 digits */ 00883 return -1; 00884 req->rlPart2 = e; 00885 } else { /* We have a request */ 00886 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 00887 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 00888 e++; 00889 if (!*e) 00890 return -1; 00891 } 00892 req->rlPart2 = e; /* URI */ 00893 e = ast_skip_nonblanks(e); 00894 if (*e) 00895 *e++ = '\0'; 00896 e = ast_skip_blanks(e); 00897 if (strcasecmp(e, "SIP/2.0") ) { 00898 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 00899 return -1; 00900 } 00901 } 00902 return 1; 00903 }
|
|
|
Add reference for device.
Definition at line 436 of file sip3_config.c. References ast_log(), ASTOBJ_REF, LOG_DEBUG, option_debug, and sipdebug. 00437 { 00438 ASTOBJ_REF(device); 00439 if (option_debug > 3 && sipdebug) 00440 ast_log(LOG_DEBUG, "/// Adding reference to device %s - refcount now %d\n", device->name, device->refcount); 00441 return device; 00442 }
|
|
||||||||||||||||
|
Report Device status in character string.
Definition at line 183 of file sip3_cliami.c. References sip_device::lastms, and sip_device::maxms. Referenced by _sip_show_device(), _sip_show_devices(), and function_sippeer(). 00184 { 00185 int res = 0; 00186 if (device->maxms) { 00187 if (device->lastms < 0) { 00188 ast_copy_string(status, "UNREACHABLE", statuslen); 00189 } else if (device->lastms > device->maxms) { 00190 snprintf(status, statuslen, "LAGGED (%d ms)", device->lastms); 00191 res = 1; 00192 } else if (device->lastms) { 00193 snprintf(status, statuslen, "OK (%d ms)", device->lastms); 00194 res = 1; 00195 } else { 00196 ast_copy_string(status, "UNKNOWN", statuslen); 00197 } 00198 } else { 00199 ast_copy_string(status, "Unmonitored", statuslen); 00200 /* Checking if port is 0 */ 00201 res = -1; 00202 } 00203 return res; 00204 }
|
|
|
Remove reference for device. When we reach 0, device is removed from memory.
Definition at line 425 of file sip3_config.c. References ast_log(), ASTOBJ_UNREF, LOG_DEBUG, option_debug, sip_destroy_device(), and sipdebug. Referenced by __sip_autodestruct(), _sip_show_device(), check_user_full(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), register_verify(), sip_devicestate(), sip_do_debug_device(), and update_call_counter(). 00426 { 00427 if (!device) 00428 return; 00429 00430 if (option_debug > 3 && sipdebug) 00431 ast_log(LOG_DEBUG, "/// Removing reference from device %s - refcount now %d\n", device->name, device->refcount - 1); 00432 ASTOBJ_UNREF(device, sip_destroy_device); 00433 }
|
|
||||||||||||
|
|
Lock list of active SIP dialogs.
Definition at line 122 of file sip3_dialog.c. References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), LOG_DEBUG, option_debug, and sipdebug. 00123 { 00124 int counter = 0; 00125 while (ast_mutex_trylock(&dialoglock) && counter < 100) { 00126 if (option_debug > 4) 00127 ast_log(LOG_DEBUG, "---Trying to lock dialoglist -- %d \n", ++counter); 00128 } 00129 if (counter == 100) 00130 ast_mutex_lock(&dialoglock); 00131 if (sipdebug && option_debug > 4) 00132 ast_log(LOG_DEBUG, "=== SIP dialog list: LOCKED\n"); 00133 }
|
|
|
Unlock list of active SIP dialogs.
Definition at line 136 of file sip3_dialog.c. References ast_log(), ast_mutex_unlock(), LOG_DEBUG, option_debug, and sipdebug. 00137 { 00138 ast_mutex_unlock(&dialoglock); 00139 if (sipdebug && option_debug > 4) 00140 ast_log(LOG_DEBUG, "=== SIP dialog list: UNLOCKED\n"); 00141 }
|
|
|
Convert SIP dialog states to string.
Definition at line 162 of file sip3_dialog.c. References DIALOG_STATE_CONFIRMED, DIALOG_STATE_CONFIRMED_HOLD, DIALOG_STATE_EARLY, DIALOG_STATE_PROCEEDING, DIALOG_STATE_TERMINATED, DIALOG_STATE_TERMINATED_AUTH, and DIALOG_STATE_TRYING. Referenced by dialogstatechange(), sip_hangup(), and sip_show_channel(). 00163 { 00164 const char *reply = "<unknown>"; 00165 switch (state) { 00166 case DIALOG_STATE_TRYING: 00167 reply = "Trying"; 00168 break; 00169 case DIALOG_STATE_PROCEEDING: 00170 reply = "Proceeding"; 00171 break; 00172 case DIALOG_STATE_EARLY: 00173 reply = "Early"; 00174 break; 00175 case DIALOG_STATE_CONFIRMED: 00176 reply = "Confirmed"; 00177 break; 00178 case DIALOG_STATE_CONFIRMED_HOLD: 00179 reply = "Confirmed, on hold"; 00180 break; 00181 case DIALOG_STATE_TERMINATED: 00182 reply = "Terminated"; 00183 break; 00184 case DIALOG_STATE_TERMINATED_AUTH: 00185 reply = "Terminated, auth"; 00186 break; 00187 } 00188 return reply; 00189 }
|
|
||||||||||||
|
Change dialog state for a SIP dialog and output to debug.
Definition at line 192 of file sip3_dialog.c. References append_history, ast_log(), dialogstate2str(), global, sip_dialog::icseq, LOG_DEBUG, sip_dialog::ocseq, option_debug, sip_globals::recordhistory, sipdebug, and sip_dialog::state. Referenced by handle_request(), handle_request_info(), handle_request_invite(), handle_request_subscribe(), handle_response_invite(), handle_response_notify(), handle_response_peerpoke(), sip_alloc(), sip_answer(), sip_hangup(), sip_indicate(), and transmit_final_response(). 00193 { 00194 if (dialog->state == newstate) { 00195 if (option_debug > 3) 00196 ast_log(LOG_DEBUG, "Asked to change state to dialog that already has requested state: %s State %s\n", dialog->callid, dialogstate2str(newstate)); 00197 } else { 00198 dialog->state = newstate; 00199 if (sipdebug && option_debug > 1) 00200 ast_log(LOG_DEBUG, "-- Dialog %s changed state to %s\n", dialog->callid, dialogstate2str(newstate)); 00201 if (global.recordhistory) 00202 append_history(dialog, "DialogState", "New state: %s O-Cseq %d I-Cseq %d", dialogstate2str(newstate), dialog->ocseq, dialog->icseq); 00203 } 00204 /* When state is terminated, keep it for 32 secs to allow for retransmits 00205 */ 00206 }
|
|
||||||||||||||||||||||||
|
Add authentication on outbound SIP packet.
Definition at line 327 of file sip3_auth.c. References ast_calloc, ast_log(), sip_invite_param::auth, auth_headers(), sip_invite_param::authheader, sip_dialog::authtries, sip_dialog::inviteoptions, LOG_DEBUG, option_debug, reply_digest(), SIP_INVITE, sip_method2txt(), and transmit_invite(). 00328 { 00329 char *header, *respheader; 00330 char digest[1024]; 00331 00332 if (!p->inviteoptions && !(p->inviteoptions = ast_calloc(1, sizeof(*p->inviteoptions)))) 00333 return -2; 00334 00335 p->authtries++; 00336 auth_headers(code, &header, &respheader); 00337 if (option_debug > 1) 00338 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_method2txt(sipmethod)); 00339 memset(digest, 0, sizeof(digest)); 00340 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 00341 /* No way to authenticate */ 00342 return -1; 00343 } 00344 /* Now we have a reply digest */ 00345 p->inviteoptions->auth = digest; 00346 p->inviteoptions->authheader = respheader; 00347 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 00348 }
|
|
||||||||||||||||
|
Authenticate for outbound registration.
Definition at line 303 of file sip3_auth.c. References append_history, ast_test_flag, ast_verbose(), auth_headers(), sip_dialog::authtries, sip_dialog::flags, reply_digest(), sip_debug_test_pvt(), SIP_NO_HISTORY, SIP_REGISTER, and transmit_register(). 00304 { 00305 char *header, *respheader; 00306 char digest[1024]; 00307 00308 p->authtries++; 00309 auth_headers(code, &header, &respheader); 00310 memset(digest,0,sizeof(digest)); 00311 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 00312 /* There's nothing to use for authentication */ 00313 /* No digest challenge in request */ 00314 if (sip_debug_test_pvt(p) && p->registry) 00315 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 00316 /* No old challenge */ 00317 return -1; 00318 } 00319 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 00320 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 00321 if (sip_debug_test_pvt(p) && p->registry) 00322 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 00323 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 00324 }
|
|
||||||||||||
|
Set nat mode on the various media streams.
Definition at line 668 of file chan_sip3.c. References ast_log(), ast_rtp_setnat(), ast_udptl_setnat(), LOG_DEBUG, option_debug, sip_dialog::rtp, sip_dialog::udptl, and sip_dialog::vrtp. 00669 { 00670 const char *mode = natflags ? "On" : "Off"; 00671 00672 if (dialog->rtp) { 00673 if (option_debug) 00674 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 00675 ast_rtp_setnat(dialog->rtp, natflags); 00676 } 00677 if (dialog->vrtp) { 00678 if (option_debug) 00679 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 00680 ast_rtp_setnat(dialog->vrtp, natflags); 00681 } 00682 if (dialog->udptl) { 00683 if (option_debug) 00684 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 00685 ast_udptl_setnat(dialog->udptl, natflags); 00686 } 00687 }
|
|
|
The SIP monitoring thread.
Definition at line 249 of file sip3_monitor.c. References ast_io_add(), ast_io_change(), AST_IO_IN, ast_verbose(), FALSE, io, option_verbose, sip_network::read_id, sip_do_reload(), sip_reload_check(), sipnet, sip_network::sipsock, sipsock_read(), sipsocket_initialized(), and VERBOSE_PREFIX_1. Referenced by restart_monitor(). 00250 { 00251 int res; 00252 struct sip_dialog *sip; 00253 struct sip_device *device = NULL; 00254 time_t now; 00255 int fastrestart = FALSE; 00256 int lastpeernum = -1; 00257 int curpeernum; 00258 static int nowalkmessage = 0; 00259 00260 /* Add an I/O event to our SIP UDP socket */ 00261 if (sipsocket_initialized(&sipnet)) 00262 sipnet.read_id = ast_io_add(io, sipnet.sipsock, sipsock_read, AST_IO_IN, NULL); 00263 00264 /* From here on out, we die whenever asked */ 00265 for(;;) { 00266 /*------ Check for a reload request */ 00267 if (sip_reload_check()) { 00268 if (option_verbose > 0) 00269 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 00270 sip_do_reload(); 00271 00272 /* Change the I/O fd of our UDP socket */ 00273 if (sipsocket_initialized(&sipnet)) 00274 sipnet.read_id = ast_io_change(io, sipnet.read_id, sipnet.sipsock, NULL, 0, NULL); 00275 } 00276 00277 /*----- Check for interfaces needing to be killed */ 00278 if (dialoglist != NULL && !fastrestart) { 00279 struct sip_dialog *nextdialog; 00280 00281 if (option_debug > 4) 00282 ast_log(LOG_DEBUG, ":: MONITOR :: Walking dialog list.\n"); 00283 dialoglist_lock(); 00284 restartsearch: 00285 now = time(NULL); 00286 /* don't scan the interface list if it hasn't been a reasonable period 00287 of time since the last time we did it (when MWI is being sent, we can 00288 get back to this point every millisecond or less) 00289 */ 00290 for (sip = dialoglist; sip; sip = nextdialog) { 00291 nextdialog = sip->next; 00292 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP or RTCP */ 00293 check_rtp_timeout(sip, now); 00294 00295 /* If we have sessions that needs to be destroyed, do it now */ 00296 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && !sip->owner) { 00297 __sip_destroy(sip, TRUE, FALSE); 00298 //goto restartsearch; 00299 } 00300 } 00301 dialoglist_unlock(); 00302 nowalkmessage = 0; 00303 } else if (!fastrestart && sipdebug && option_debug > 4) { 00304 if (!nowalkmessage) 00305 ast_log(LOG_DEBUG, ":: MONITOR :: Empty dialog list. Pausing channel walks\n"); 00306 nowalkmessage = 1; 00307 } 00308 00309 pthread_testcancel(); 00310 00311 /*------ Wait for sched or io */ 00312 res = ast_sched_wait(sched); 00313 00314 if ((res < 0) || (res > 1000)) 00315 res = 1000; 00316 /* If we might need to send more mailboxes, don't wait long at all.*/ 00317 if (fastrestart) 00318 res = 1; 00319 00320 res = ast_io_wait(io, res); 00321 if (option_debug && res > 20) 00322 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 00323 ast_mutex_lock(&monlock); 00324 if (res >= 0) { 00325 res = ast_sched_runq(sched); /* Check for scheduled items, like retransmits */ 00326 if (option_debug && res >= 20) 00327 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 00328 } 00329 00330 /*----- Send MWI notifications to devices - static and cached realtime peers */ 00331 if (sipcounters.peers_with_mwi > 0 ) { 00332 fastrestart = FALSE; 00333 curpeernum = 0; 00334 device= NULL; 00335 /* Find next device that needs mwi */ 00336 ASTOBJ_CONTAINER_TRAVERSE(&devicelist, !device, do { 00337 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 00338 fastrestart = TRUE; 00339 lastpeernum = curpeernum; 00340 device = device_ref(iterator); 00341 }; 00342 curpeernum++; 00343 } while (0) 00344 ); 00345 /* Send MWI to the peer */ 00346 if (device) { 00347 ASTOBJ_WRLOCK(device); 00348 sip_send_mwi_to_peer(device); 00349 ASTOBJ_UNLOCK(device); 00350 device_unref(device); 00351 } else { 00352 /* Reset where we come from */ 00353 lastpeernum = -1; 00354 } 00355 } 00356 ast_mutex_unlock(&monlock); 00357 } 00358 /* Never reached */ 00359 return NULL; 00360 00361 }
|
|
|
Print domain mode to cli.
Definition at line 191 of file sip3_domain.c. References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG. 00192 { 00193 switch (mode) { 00194 case SIP_DOMAIN_AUTO: 00195 return "[Automatic]"; 00196 case SIP_DOMAIN_CONFIG: 00197 return "[Configured]"; 00198 } 00199 00200 return ""; 00201 }
|
|
|
return TRUE if any domains are configured for this server
Definition at line 125 of file sip3_domain.c. References AST_LIST_EMPTY. Referenced by get_destination(), handle_request_refer(), register_verify(), sip_show_domains(), and sip_show_settings(). 00126 { 00127 return (!AST_LIST_EMPTY(&domain_list)); 00128 }
|
|
|
Expire registration of SIP peer.
Definition at line 391 of file sip3_objects.c. References sip_device::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, destroy_association(), device_unref(), devicelist, EVENT_FLAG_SYSTEM, sip_device::expire, FALSE, sip_device::flags, manager_event, register_peer_exten(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT. 00392 { 00393 struct sip_device *device = data; 00394 00395 if (!device) /* Hmmm. We have no peer. Weird. */ 00396 return 0; 00397 00398 memset(&device->addr, 0, sizeof(device->addr)); 00399 00400 destroy_association(device); /* remove registration data from storage */ 00401 00402 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", device->name); 00403 register_peer_exten(device, FALSE); /* Remove regexten */ 00404 device->expire = -1; 00405 ast_device_state_changed("SIP/%s", device->name); 00406 00407 /* Do we need to release this peer from memory? 00408 Only for realtime peers and autocreated peers 00409 */ 00410 if (ast_test_flag(&device->flags[1], SIP_PAGE2_SELFDESTRUCT) || 00411 ast_test_flag(&device->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 00412 device = ASTOBJ_CONTAINER_UNLINK(&devicelist, device); /* Remove from peer list */ 00413 device_unref(device); 00414 } 00415 00416 return 0; 00417 }
|
|
||||||||||||
|
Check Contact: URI of SIP message.
Definition at line 906 of file sip3_parse.c. References ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and strsep(). 00907 { 00908 char stripped[256]; 00909 char *c; 00910 00911 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 00912 c = get_in_brackets(stripped); 00913 c = strsep(&c, ";"); /* trim ; and beyond */ 00914 if (!ast_strlen_zero(c)) 00915 ast_string_field_set(p, uri, c); 00916 }
|
|
||||||||||||
|
Find compressed SIP alias Structure for conversion between compressed SIP and "normal" SIP.
Definition at line 320 of file sip3_parse.c. References aliases. 00321 { 00322 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 00323 static const struct cfalias { 00324 char * const fullname; 00325 char * const shortname; 00326 } aliases[] = { 00327 { "Content-Type", "c" }, 00328 { "Content-Encoding", "e" }, 00329 { "From", "f" }, 00330 { "Call-ID", "i" }, 00331 { "Contact", "m" }, 00332 { "Content-Length", "l" }, 00333 { "Subject", "s" }, 00334 { "To", "t" }, 00335 { "Supported", "k" }, 00336 { "Refer-To", "r" }, 00337 { "Referred-By", "b" }, 00338 { "Allow-Events", "u" }, 00339 { "Event", "o" }, 00340 { "Via", "v" }, 00341 { "Accept-Contact", "a" }, 00342 { "Reject-Contact", "j" }, 00343 { "Request-Disposition", "d" }, 00344 { "Session-Expires", "x" }, 00345 { "Identity", "y" }, 00346 { "Identity-Info", "n" }, 00347 }; 00348 int x; 00349 00350 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 00351 if (!strcasecmp(aliases[x].fullname, name)) 00352 return aliases[x].shortname; 00353 00354 return _default; 00355 }
|
|
||||||||||||||||
|
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name. Definition at line 242 of file sip3_objects.c. References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, devicelist, name, realtime_peer(), and sip_addrcmp(). Referenced by _sip_show_device(), check_user_full(), create_addr(), function_sippeer(), register_verify(), sip_devicestate(), sip_do_debug_device(), sip_peer_hold(), and update_call_counter(). 00243 { 00244 struct sip_device *peer = NULL; 00245 00246 if (device) 00247 peer = ASTOBJ_CONTAINER_FIND(&devicelist, device); 00248 else 00249 peer = ASTOBJ_CONTAINER_FIND_FULL(&devicelist, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 00250 00251 if (!peer && realtime) 00252 peer = realtime_peer(device, sin); 00253 00254 return peer; 00255 }
|
|
||||||||||||
|
Find authentication for a specific realm.
Definition at line 569 of file sip3_auth.c. References sip_auth::next, and sip_auth::realm. 00570 { 00571 struct sip_auth *a; 00572 00573 for (a = authlist; a; a = a->next) { 00574 if (!strcasecmp(a->realm, realm)) 00575 break; 00576 } 00577 00578 return a; 00579 }
|
|
|
Determine whether a SIP message contains an SDP in its body.
Definition at line 880 of file sip3_sdprtp.c. References ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::line, sip_request::lines, sip_request::sdp_end, sip_request::sdp_start, strcasestr(), and TRUE. 00881 { 00882 const char *content_type; 00883 const char *search; 00884 char *boundary; 00885 unsigned int x; 00886 00887 content_type = get_header(req, "Content-Type"); 00888 00889 /* if the body contains only SDP, this is easy */ 00890 if (!strcasecmp(content_type, "application/sdp")) { 00891 req->sdp_start = 0; 00892 req->sdp_end = req->lines; 00893 return TRUE; 00894 } 00895 00896 /* if it's not multipart/mixed, there cannot be an SDP */ 00897 if (strncasecmp(content_type, "multipart/mixed", 15)) 00898 return FALSE; 00899 00900 /* if there is no boundary marker, it's invalid */ 00901 if (!(search = strcasestr(content_type, ";boundary="))) 00902 return FALSE; 00903 00904 search += 10; 00905 00906 if (ast_strlen_zero(search)) 00907 return FALSE; 00908 00909 /* make a duplicate of the string, with two extra characters 00910 at the beginning */ 00911 boundary = ast_strdupa(search - 2); 00912 boundary[0] = boundary[1] = '-'; 00913 00914 /* search for the boundary marker, but stop when there are not enough 00915 lines left for it, the Content-Type header and at least one line of 00916 body */ 00917 for (x = 0; x < (req->lines - 2); x++) { 00918 if (!strncasecmp(req->line[x], boundary, strlen(boundary)) && 00919 !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) { 00920 x += 2; 00921 req->sdp_start = x; 00922 /* search for the end of the body part */ 00923 for ( ; x < req->lines; x++) { 00924 if (!strncasecmp(req->line[x], boundary, strlen(boundary))) 00925 break; 00926 } 00927 req->sdp_end = x; 00928 return TRUE; 00929 } 00930 } 00931 00932 return FALSE; 00933 }
|
|
|
find_sip_method: Find SIP method from header
Definition at line 163 of file sip3_parse.c. References ast_strlen_zero(), method_match(), and sip_methods. 00164 { 00165 int i, res = 0; 00166 00167 if (ast_strlen_zero(msg)) 00168 return 0; 00169 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 00170 if (method_match(i, msg)) 00171 res = sip_methods[i].id; 00172 } 00173 return res; 00174 }
|
|
|
Find subscription type in array.
Definition at line 119 of file sip3_subscribe.c. References subscription_types, and type. 00120 { 00121 int i; 00122 00123 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 00124 if (subscription_types[i].type == subtype) { 00125 return &subscription_types[i]; 00126 } 00127 } 00128 return &subscription_types[0]; 00129 }
|
|
||||||||||||||||
|
Find via branch parameter.
Definition at line 1196 of file sip3_dialog.c. References ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, LOG_DEBUG, option_debug, SIP_PKT_DEBUG, strcasestr(), and sip_request::via. Referenced by match_or_create_dialog(). 01197 { 01198 char *dupvia; 01199 char *viabranch; 01200 char *sep; 01201 01202 if (ast_strlen_zero(req->via)) 01203 return; 01204 dupvia = ast_strdupa(req->via); 01205 if (!(viabranch = strcasestr(dupvia, ";branch="))) 01206 return; 01207 viabranch += 8; 01208 if ((sep = strchr(viabranch, ';'))) 01209 *sep = '\0'; 01210 if (ast_test_flag(req, SIP_PKT |