Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:52 2007

Asterisk developer's documentation :: Codename Pineapple


sip3_network.c File Reference


Detailed Description

Various SIP network interface functions Version 3 of chan_sip.

Author:
Mark Spencer <markster@digium.com>

Olle E. Johansson <oej@edvina.net> (all the chan_sip3 changes)

See Also:

Definition in file sip3_network.c.

#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "sip3.h"
#include "sip3funcs.h"

Include dependency graph for sip3_network.c:

Go to the source code of this file.

Data Structures

struct  sip_queue_item

Functions

static enum sip_result __sip_reliable_xmit (struct sip_network *sipnet, struct sip_dialog *dialog, int resp, struct sip_request *req, int fatal)
 Transmit packet with retransmits.
static int __sip_xmit (struct sip_network *sipnet, struct sip_dialog *p, struct sip_request *req)
 Transmit SIP message.
static void append_send_history (struct sip_dialog *dialog, struct sip_request *req, struct sip_network *sipnet, int reliable, int response)
 Append history of sending request or response to dialog.
static AST_LIST_HEAD_STATIC (sip_queue, sip_queue_item)
int close_sip_sockets ()
 Close all open network sockets.
static void parse_copy (struct sip_request *dst, const struct sip_request *src)
 Copy SIP request, pre-parse it.
void process_sip_queue ()
 Process one item off the SIP queue.
static void queue_sip_request (struct sip_request *request, struct sockaddr_in *sin)
 queue incoming SIP request onto sip_queue for processing
void reset_ip_interface (struct sip_network *sipnet)
 clear IP interfaces
static int retrans_pkt (void *data)
 Retransmit SIP message if no answer (Called from scheduler).
int send_request (struct sip_dialog *p, struct sip_request *req, enum xmittype reliable)
 Send SIP Request to the other part of the dialogue.
int send_response (struct sip_dialog *p, struct sip_request *req, enum xmittype reliable)
 Transmit response on SIP request.
int sip_debug_test_addr (const struct sockaddr_in *addr)
 See if we pass debug IP filter.
int sip_debug_test_level (int sipmethod)
int sip_debug_test_pvt (struct sip_dialog *p)
 Test PVT for debugging output.
enum sip_result sip_ouraddrfor (struct in_addr *them, struct in_addr *us)
 NAT fix - decide which IP address to use for Asterisk server?
const struct sockaddr_in * sip_real_dst (const struct sip_dialog *p)
 The real destination address for a write.
void sipnet_lock (struct sip_network *sipnet)
 Lock netlock.
static void sipnet_lock_init (struct sip_network *sipnet)
 Initialize network lock.
int sipnet_ourport (struct sip_network *sipnet)
 read our port number
void sipnet_ourport_set (struct sip_network *sipnet, int port)
 Set our port number.
void sipnet_unlock (struct sip_network *sipnet)
 Unlock netlock.
sip_requestsiprequest_alloc (size_t len, struct sip_network *sipnet)
 Allocate SIP request structure.
void siprequest_free (struct sip_request *req)
 Free SIP request.
int sipsock_init (struct sip_network *sipnet, struct sockaddr_in *old_bindaddr)
 Initialize IP socket on configured address - the bind address.
int sipsock_read (int *id, int fd, short events, void *ignore)
 Read data from SIP socket.
int sipsocket_initialized (struct sip_network *sipnet)
 Check if network socket is open.
int sipsocket_open (struct sip_network *sipnet)
 Open network socket, bind to address and set options (TOS).

Variables

sip_globals global
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
sip_network sipnet


Function Documentation

static enum sip_result __sip_reliable_xmit struct sip_network sipnet,
struct sip_dialog dialog,
int  resp,
struct sip_request req,
int  fatal
[static]
 

Transmit packet with retransmits.

Note:
the packet is stored in the PVT until we have a reply...
Returns:
0 on success, -1 on failure to allocate packet

Definition at line 623 of file sip3_network.c.

References __sip_xmit(), AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_set_flag, AST_SUCCESS, DEFAULT_RETRANS, sip_request::dialog, LOG_DEBUG, sip_request::next, option_debug, sip_dialog::packets, sip_dialog::pendinginvite, retrans_pkt(), SIP_INVITE, SIP_PKT_CONNECTED, SIP_PKT_FATAL, SIP_PKT_RESPONSE, sipdebug, sipnet, and sip_dialog::timer_t1.

00625 {
00626    int siptimer_a = DEFAULT_RETRANS;
00627    enum sip_result res= AST_FAILURE;
00628 
00629    ast_set_flag(req, SIP_PKT_CONNECTED);  /* Stop sipsock_read from free'ing this request */
00630    req->next = dialog->packets;
00631    req->dialog = dialog;
00632    if (resp)
00633       ast_set_flag(req, SIP_PKT_RESPONSE);
00634    req->timer_t1 = dialog->timer_t1;   /* Set SIP timer T1 */
00635    /* If this is critical for the success of this transaction, mark it FATAL
00636       the dialog will fail if this is not accepted */
00637    if (fatal)
00638       ast_set_flag(req, SIP_PKT_FATAL);
00639    if (req->timer_t1)
00640       siptimer_a = req->timer_t1 * 2;
00641 
00642    /* Schedule retransmission */
00643    req->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, req, 1);
00644 
00645    if (option_debug > 3 && sipdebug)
00646       ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id  #%d\n", req->retransid);
00647    /* XXX Are we locked? Any chance of messing up here? */
00648    req->next = dialog->packets;
00649    dialog->packets = req;
00650 
00651    /* Send packet */
00652    if (!__sip_xmit(sipnet, req->dialog, req))
00653       res = AST_FAILURE;
00654    else
00655       res = AST_SUCCESS;
00656 
00657 
00658    if (req->method == SIP_INVITE) {
00659       /* Note this is a pending invite */
00660       dialog->pendinginvite = req->seqno;
00661    }
00662    return res;
00663 }

static int __sip_xmit struct sip_network sipnet,
struct sip_dialog p,
struct sip_request req
[static]
 

Transmit SIP message.

Returns:
0 if successful, -1 to cancel retransmits and give up due to network failure

Definition at line 480 of file sip3_network.c.

References ast_inet_ntoa(), ast_log(), sip_request::data, sip_request::len, LOG_WARNING, sip_real_dst(), sipnet, and sip_network::sipsock.

00481 {
00482    int res;
00483    const struct sockaddr_in *dst = sip_real_dst(p);
00484 
00485    /* XXX in the future, we need to make sure we follow the current flow for this dialog  - TCP, UDP */
00486    res = sendto(sipnet->sipsock, req->data, req->len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
00487 
00488    if (res != req->len) {
00489       ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", req->data, req->len, ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno));
00490       /* If one of this errors are returned, we should propably
00491          cancel retransmits and give up */
00492       if (errno == EHOSTUNREACH) {  /* No route to host */
00493       }
00494       if (errno == EHOSTDOWN) {  /* No route to host */
00495       }
00496       return -1;
00497    }  
00498    return 0;
00499 }

static void append_send_history struct sip_dialog dialog,
struct sip_request req,
struct sip_network sipnet,
int  reliable,
int  response
[static]
 

Append history of sending request or response to dialog.

Note:
This is quite a stupid function, that allocates an extra packet in memory just for the debug message...

Definition at line 691 of file sip3_network.c.

References append_history, sip_request::data, sip_request::data_size, sip_request::dialog, get_header(), sip_request::method, parse_copy(), sip_request::rlPart2, sip_method2txt(), SIP_RESPONSE, SIP_UNKNOWN, sipnet, siprequest_alloc(), and siprequest_free().

Referenced by send_request(), and send_response().

00692 {
00693    struct sip_request *tmp;
00694 
00695    tmp = siprequest_alloc(req->data_size, sipnet);
00696    parse_copy(tmp, req);
00697    if (response)
00698       append_history(dialog, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp->data, get_header(tmp, "CSeq"), 
00699          (tmp->method == SIP_RESPONSE || tmp->method == SIP_UNKNOWN) ? tmp->rlPart2 : sip_method2txt(tmp->method));
00700    else
00701       append_history(dialog, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp->data, get_header(tmp, "CSeq"), sip_method2txt(tmp->method));
00702    siprequest_free(tmp);
00703 }

static AST_LIST_HEAD_STATIC sip_queue  ,
sip_queue_item 
[static]
 

int close_sip_sockets void   ) 
 

Close all open network sockets.

Definition at line 185 of file sip3_network.c.

References sipnet, sip_network::sipsock, and TRUE.

00186 {
00187    /* Start with sipnet */
00188    close(sipnet.sipsock);
00189    return TRUE;
00190 }

static void parse_copy struct sip_request dst,
const struct sip_request src
[static]
 

Copy SIP request, pre-parse it.

Definition at line 666 of file sip3_network.c.

References ast_calloc, sip_request::data, sip_request::data_size, free, sip_request::len, and parse_request().

00667 {
00668    memset(dst, 0, sizeof(*dst));
00669    /* If we have data memory allocated in destination, check if it's 
00670       enough. Otherwise, release it */
00671    if (dst->data && dst->data_size <= src->data_size)
00672       free(dst->data);
00673 
00674    /* Allocate memory if we don't have any or not enough */
00675    if (!dst->data) {
00676       dst->data = ast_calloc(1, src->data_size);
00677       dst->data_size = src->data_size;
00678    }
00679 
00680    /* Copy data block */
00681    memcpy(dst->data, src->data, dst->data_size);
00682 
00683    dst->len = src->len;
00684    parse_request(dst);
00685 }

void process_sip_queue void   ) 
 

Process one item off the SIP queue.

Definition at line 338 of file sip3_network.c.

References append_history, ast_channel_trylock, ast_channel_unlock, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log(), ast_test_flag, ast_update_use_count(), sip_request::data, dialog_lock(), FALSE, sip_dialog::flags, free, get_header(), handle_request(), sip_request::len, LOG_DEBUG, LOG_ERROR, match_or_create_dialog(), sip_request::method, option_debug, sip_dialog::owner, sip_dialog::recv, sip_queue_item::request, sip_request::rlPart2, sip_queue_item::sin, SIP_NO_HISTORY, SIP_PKT_CONNECTED, SIP_PKT_INITREQ, sipnet, sipnet_lock(), sipnet_unlock(), and transmit_response().

Referenced by sipsock_read().

00339 {
00340    struct sip_request *req;
00341    struct sip_queue_item *item;
00342    struct sockaddr_in *sin;
00343    struct sip_dialog *p;
00344    int nounlock;
00345    int recount = 0;
00346    unsigned int lockretry = 100;
00347 
00348    /* Anything to process? */
00349    if (AST_LIST_EMPTY(&sip_queue))
00350       return;
00351 
00352    AST_LIST_LOCK(&sip_queue);
00353    item = AST_LIST_REMOVE_HEAD(&sip_queue, list);
00354    AST_LIST_UNLOCK(&sip_queue);
00355 
00356    req = item->request;
00357    sin = &item->sin;
00358 
00359    /* Process request, with netlock held */
00360 retrylock:
00361    sipnet_lock(&sipnet);
00362 
00363    /* Find the active SIP dialog or create a new one */
00364    p = match_or_create_dialog(req, sin, req->method); /* returns p locked */
00365    if (p == NULL) {
00366       if (option_debug)
00367          ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req->len);
00368    } else {
00369       /* Go ahead and lock the owner if it has one -- we may need it */
00370       /* becaues this is deadlock-prone, we need to try and unlock if failed */
00371       if (p->owner && ast_channel_trylock(p->owner)) {
00372          if (option_debug)
00373             ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid);
00374          dialog_lock(p, FALSE);
00375          sipnet_unlock(&sipnet);
00376          /* Sleep for a very short amount of time */
00377          usleep(1);
00378          if (--lockretry)
00379             goto retrylock;
00380       }
00381       p->recv = item->sin;
00382 
00383       if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */
00384          append_history(p, "Rx", "%s / %s / %s", req->data, get_header(req, "CSeq"), req->rlPart2);
00385 
00386       if (!lockretry) {
00387          ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", p->owner->name ? p->owner->name : "- no channel name ??? - ");
00388          ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
00389          transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
00390                /* XXX We could add retry-after to make sure they come back */
00391          append_history(p, "LockFail", "Owner lock failed, transaction failed.");
00392          sipnet_unlock(&sipnet);
00393          return;
00394       }
00395       nounlock = 0;
00396       if (handle_request(p, req, sin, &recount, &nounlock) == -1) {
00397          /* Request failed */
00398          if (option_debug)
00399             ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
00400       }
00401       
00402       if (p->owner && !nounlock)
00403          ast_channel_unlock(p->owner);
00404       dialog_lock(p, FALSE);
00405    }
00406    sipnet_unlock(&sipnet);
00407    if (recount)
00408       ast_update_use_count();
00409    
00410    /* If this packet is not connected to a dialog, then free it. If it is connected,
00411       then let the dialog destroy it later */
00412    if (!ast_test_flag(req, SIP_PKT_CONNECTED) && !ast_test_flag(req, SIP_PKT_INITREQ)) {
00413       free(req->data);
00414       free(req);
00415    }
00416 
00417    return;
00418 }

static void queue_sip_request struct sip_request request,
struct sockaddr_in *  sin
[static]
 

queue incoming SIP request onto sip_queue for processing

Definition at line 238 of file sip3_network.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, sip_queue_item::request, and sip_queue_item::sin.

Referenced by sipsock_read().

00239 {
00240    struct sip_queue_item *item = ast_calloc(1, sizeof(struct sip_queue_item));
00241    
00242    item->request = request;
00243    /* Save IP address received from - hmm, maybe should be stored in the request instead */
00244    item->sin = *sin;
00245    AST_LIST_LOCK(&sip_queue);
00246    AST_LIST_INSERT_TAIL(&sip_queue, item, list);
00247    AST_LIST_UNLOCK(&sip_queue);
00248 }

void reset_ip_interface struct sip_network sipnet  ) 
 

clear IP interfaces

Definition at line 136 of file sip3_network.c.

References sip_network::bindaddr, DEFAULT_LISTEN_SIP_PORT, sip_network::externexpire, sip_network::externhost, sip_network::externip, sip_network::externrefresh, sip_network::localaddr, sip_network::outboundproxyip, sipnet, sipnet_ourport_set(), and STANDARD_SIP_PORT.

Referenced by reload_config().

00137 {
00138    /* Reset IP addresses  */
00139    memset(&sipnet->bindaddr, 0, sizeof(sipnet->bindaddr));
00140    memset(&sipnet->localaddr, 0, sizeof(sipnet->localaddr));
00141    memset(&sipnet->externip, 0, sizeof(sipnet->externip));
00142 
00143    sipnet->outboundproxyip.sin_port = htons(STANDARD_SIP_PORT);
00144    sipnet->outboundproxyip.sin_family = AF_INET;   /* Type of address: IPv4 */
00145    memset(&sipnet->outboundproxyip, 0, sizeof(sipnet->outboundproxyip));
00146 
00147    sipnet_ourport_set(sipnet, DEFAULT_LISTEN_SIP_PORT);
00148    sipnet->externhost[0] = '\0';       /* External host name (for behind NAT DynDNS support) */
00149    sipnet->externexpire = 0;        /* Expiration for DNS re-issuing */
00150    sipnet->externrefresh = 10;
00151 
00152 }

static int retrans_pkt void *  data  )  [static]
 

Retransmit SIP message if no answer (Called from scheduler).

Definition at line 503 of file sip3_network.c.

References __sip_xmit(), append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_request::data, DEFAULT_RETRANS, sip_request::dialog, dialog_lock(), FALSE, sip_dialog::flags, global, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_request::method, sip_request::next, option_debug, option_verbose, sip_dialog::owner, sip_dialog::packets, sip_request::retrans, sip_request::retransid, SIP_ALREADYGONE, sip_debug_test_pvt(), SIP_INVITE, sip_method2txt(), sip_nat_mode(), SIP_NEEDDESTROY, SIP_OPTIONS, SIP_PKT_FATAL, SIP_PKT_RESPONSE, sip_real_dst(), sipdebug, sipnet, siprequest_free(), sip_globals::t2default, sip_request::timer_a, sip_request::timer_t1, and TRUE.

00504 {
00505    struct sip_request *pkt = data, *prev, *cur = NULL;
00506    int reschedule = DEFAULT_RETRANS;
00507 
00508    if (!pkt->dialog) {
00509       ast_log(LOG_WARNING, "Trying to retransmit packet without dialog owner...  id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_method2txt(pkt->method), pkt->method);
00510       return 0;
00511    }
00512    /* Lock channel PVT */
00513    dialog_lock(pkt->dialog, TRUE);
00514 
00515    if (pkt->retrans < MAX_RETRANS) {
00516       pkt->retrans++;
00517       if (!pkt->timer_t1) {   /* Re-schedule using timer_a and timer_t1 */
00518          if (sipdebug && option_debug > 3)
00519             ast_log(LOG_DEBUG, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_method2txt(pkt->method), pkt->method);
00520       } else {
00521          int siptimer_a;
00522 
00523          if (sipdebug && option_debug > 3)
00524             ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_method2txt(pkt->method), pkt->method);
00525          if (!pkt->timer_a)
00526             pkt->timer_a = 2 ;
00527          else
00528             pkt->timer_a = 2 * pkt->timer_a;
00529  
00530          /* For non-invites, a maximum of 4 secs */
00531          siptimer_a = pkt->timer_t1 * pkt->timer_a;   /* Double each time */
00532          /* Timer T2 - maximum retransmit time for non-invite requests */
00533          if (pkt->method != SIP_INVITE && siptimer_a > global.t2default)
00534             siptimer_a = global.t2default;   /* T2 defaults to 4 secs */
00535       
00536          /* Reschedule re-transmit */
00537          reschedule = siptimer_a;
00538          if (option_debug > 3)
00539             ast_log(LOG_DEBUG, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", pkt->retrans +1, siptimer_a, pkt->timer_t1, pkt->retransid);
00540       } 
00541 
00542       if (sip_debug_test_pvt(pkt->dialog)) {
00543          const struct sockaddr_in *dst = sip_real_dst(pkt->dialog);
00544          ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n",
00545             pkt->retrans, sip_nat_mode(pkt->dialog),
00546             ast_inet_ntoa(dst->sin_addr),
00547             ntohs(dst->sin_port), pkt->data);
00548       }
00549 
00550       if(!__sip_xmit(&sipnet, pkt->dialog, pkt)) {
00551          append_history(pkt->dialog, "ReTx", "%d %s", reschedule, pkt->data);
00552          /* success. Go on as before */
00553          dialog_lock(pkt->dialog, FALSE);
00554          return  reschedule;
00555       }
00556       /* Houston, we do have a problem. give up and stop
00557          retransmitting. Issue a warning only if we have verbosity.
00558        */
00559       if (option_verbose > 1)
00560          ast_log(LOG_WARNING, "Network failure transmitting to host, giving up retransmissions.\n");
00561       append_history(pkt->dialog, "ReTxCancel", "Cancelled retransmits. Network problem.");
00562       /* Fall through */
00563    } 
00564    /* Too many retries */
00565    if (pkt->dialog && pkt->method != SIP_OPTIONS) {
00566       if (ast_test_flag(pkt, SIP_PKT_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */
00567          ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s)\n", pkt->dialog->callid, pkt->seqno, (ast_test_flag(pkt, SIP_PKT_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, SIP_PKT_RESPONSE)) ? "Response" : "Request");
00568    } else {
00569       if ((pkt->method == SIP_OPTIONS) && sipdebug)
00570          ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->dialog->callid);
00571    }
00572    if (pkt->retrans == MAX_RETRANS)
00573       append_history(pkt->dialog, "MaxRetries", "%s", (ast_test_flag(pkt, SIP_PKT_FATAL)) ? "(Critical)" : "(Non-critical)");
00574       
00575    pkt->retransid = -1;
00576 
00577    if (ast_test_flag(pkt, SIP_PKT_FATAL)) {
00578       while(pkt->dialog->owner && ast_channel_trylock(pkt->dialog->owner)) {
00579          dialog_lock(pkt->dialog, FALSE);
00580          usleep(1);
00581          dialog_lock(pkt->dialog, TRUE);
00582       }
00583       if (pkt->dialog->owner) {
00584          ast_set_flag(&pkt->dialog->flags[0], SIP_ALREADYGONE);
00585          ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->dialog->callid);
00586          ast_queue_hangup(pkt->dialog->owner);
00587          ast_channel_unlock(pkt->dialog->owner);
00588       } else {
00589          /* If no channel owner, destroy now 
00590             ...unless it's a SIP options packet, where
00591             we want the peerpoke expiry routine handle this.
00592          */
00593          if (pkt->method != SIP_OPTIONS)
00594             ast_set_flag(&pkt->dialog->flags[0], SIP_NEEDDESTROY);   
00595       }
00596    }
00597    /* In any case, go ahead and remove the packet */
00598    for (prev = NULL, cur = pkt->dialog->packets; cur; prev = cur, cur = cur->next) {
00599       if (cur == pkt)
00600          break;
00601    }
00602    if (cur) {
00603       if (prev)
00604          prev->next = cur->next;
00605       else
00606          pkt->dialog->packets = cur->next;
00607       dialog_lock(pkt->dialog, FALSE);
00608       if (option_debug > 3)
00609          ast_log(LOG_DEBUG, "Deleting packet from dialog list...%s\n", pkt->dialog->callid);
00610       siprequest_free(cur);
00611       pkt = NULL;
00612    } else
00613       ast_log(LOG_WARNING, "Weird, couldn't find packet dialog!\n");
00614    if (pkt)
00615       dialog_lock(pkt->dialog, FALSE);
00616    return 0;
00617 }

int send_request struct sip_dialog p,
struct sip_request req,
enum xmittype  reliable
 

Send SIP Request to the other part of the dialogue.

Definition at line 731 of file sip3_network.c.

References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_send_history(), ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, FALSE, sip_dialog::flags, sip_request::len, sip_dialog::recv, sip_dialog::sa, sip_debug_test_pvt(), SIP_NAT_ROUTE, SIP_NO_HISTORY, and sipnet.

00732 {
00733    int res;
00734 
00735    add_blank(req);
00736    if (sip_debug_test_pvt(p)) {
00737       if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
00738          ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port), req->data);
00739       else
00740          ast_verbose("--- %sTransmitting (no NAT) to %s:%d (size %u):\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port), req->len, req->data);
00741    }
00742    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
00743       append_send_history(p, req, &sipnet, reliable, FALSE);
00744    res = (reliable) ?
00745       __sip_reliable_xmit(&sipnet, p, 0, req, (reliable > 1)) :
00746       __sip_xmit(&sipnet, p, req);
00747    return res;
00748 }

int send_response struct sip_dialog p,
struct sip_request req,
enum xmittype  reliable
 

Transmit response on SIP request.

Definition at line 706 of file sip3_network.c.

References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_send_history(), ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_dialog::flags, sip_debug_test_pvt(), sip_nat_mode(), SIP_NO_HISTORY, sip_real_dst(), sipnet, TRUE, and XMIT_CRITICAL.

00707 {
00708    int res;
00709 
00710    add_blank(req);
00711    if (sip_debug_test_pvt(p)) {
00712       const struct sockaddr_in *dst = sip_real_dst(p);
00713 
00714       ast_verbose("%sTransmitting (%s) to %s:%d:\n%s\n---\n",
00715          reliable ? "Reliably " : "", sip_nat_mode(p),
00716          ast_inet_ntoa(dst->sin_addr),
00717          ntohs(dst->sin_port), req->data);
00718    }
00719    /* This is stupid - allocate a copy of the request just to add history... */
00720    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
00721       append_send_history(p, req, &sipnet, reliable, TRUE);
00722    res = (reliable) ?
00723       __sip_reliable_xmit(&sipnet, p, 1, req, (reliable == XMIT_CRITICAL)) :
00724       __sip_xmit(&sipnet, p, req);
00725    if (res > 0)
00726       return 0;
00727    return res;
00728 }

int sip_debug_test_addr const struct sockaddr_in *  addr  )  [inline]
 

See if we pass debug IP filter.

Definition at line 758 of file sip3_network.c.

References sip_network::debugaddr, sipdebug, and sipnet.

00759 {
00760    if (!sipdebug)
00761       return 0;
00762    if (sipnet.debugaddr.sin_addr.s_addr) {
00763       if (((ntohs(sipnet.debugaddr.sin_port) != 0)
00764          && (sipnet.debugaddr.sin_port != addr->sin_port))
00765          || (sipnet.debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
00766          return 0;
00767    }
00768    return 1;
00769 }

int sip_debug_test_level int  sipmethod  )  [inline]
 

Check if the method given is included in DEBUG

Definition at line 772 of file sip3_network.c.

References sip_globals::debuglevel, FALSE, global, SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_INVITE, SIP_OPTIONS, SIP_REFER, SIPDEBUG_ALL, SIPDEBUG_NOPOKE, and TRUE.

Referenced by sipsock_read().

00773 {
00774 /*
00775    SIPDEBUG_ALL = 0,       All requests and responses 
00776         SIPDEBUG_CALLS,         INVITE, CANCEL, ACK & BYE 
00777         SIPDEBUG_NOPOKE,        Everything BUT OPTIONS 
00778 */
00779    if (global.debuglevel == SIPDEBUG_ALL) {
00780       return TRUE;
00781    } 
00782    if (global.debuglevel == SIPDEBUG_NOPOKE) {
00783       if (sipmethod == SIP_OPTIONS)
00784          return FALSE;
00785       return TRUE;
00786    }
00787    /* Ok, we need everything basic related to calls (no REGISTER, NOTIFY, OPTIONS or SUBSCRIBE stuff) */
00788    if (sipmethod == SIP_INVITE || sipmethod == SIP_CANCEL || sipmethod == SIP_REFER || sipmethod == SIP_BYE || sipmethod == SIP_ACK)
00789       return TRUE;
00790    return FALSE;
00791 }

int sip_debug_test_pvt struct sip_dialog p  )  [inline]
 

Test PVT for debugging output.

Definition at line 794 of file sip3_network.c.

References sip_debug_test_addr(), sip_real_dst(), and sipdebug.

00795 {
00796    if (!sipdebug)
00797       return 0;
00798    return sip_debug_test_addr(sip_real_dst(p));
00799 }

enum sip_result sip_ouraddrfor struct in_addr *  them,
struct in_addr *  us
 

NAT fix - decide which IP address to use for Asterisk server?

Using the localaddr structure built up with localnet statements in sip.conf apply it to their address to see if we need to substitute our externip or can get away with our internal bindaddr

Definition at line 807 of file sip3_network.c.

References ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, sip_network::bindaddr, sip_network::externexpire, sip_network::externhost, sip_network::externip, sip_network::externrefresh, hp, sip_network::localaddr, LOG_DEBUG, LOG_NOTICE, option_debug, and sipnet.

Referenced by sip_alloc(), sip_poke_peer(), sip_send_mwi_to_peer(), transmit_register(), and transmit_response_using_temp().

00808 {
00809    struct sockaddr_in theirs, ours;
00810 
00811    /* Get our local information */
00812    ast_ouraddrfor(them, us);
00813    theirs.sin_addr = *them;
00814    ours.sin_addr = *us;
00815 
00816    if (sipnet.localaddr && sipnet.externip.sin_addr.s_addr &&
00817        ast_apply_ha(sipnet.localaddr, &theirs) &&
00818        !ast_apply_ha(sipnet.localaddr, &ours)) {
00819       if (sipnet.externexpire && time(NULL) >= sipnet.externexpire) {
00820          struct ast_hostent ahp;
00821          struct hostent *hp;
00822 
00823          sipnet.externexpire = time(NULL) + sipnet.externrefresh;
00824          if ((hp = ast_gethostbyname(sipnet.externhost, &ahp))) {
00825             memcpy(&sipnet.externip.sin_addr, hp->h_addr, sizeof(sipnet.externip.sin_addr));
00826          } else
00827             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", sipnet.externhost);
00828       }
00829       *us = sipnet.externip.sin_addr;
00830       if (option_debug) {
00831          ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 
00832             ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
00833       }
00834    } else if (sipnet.bindaddr.sin_addr.s_addr)
00835       *us = sipnet.bindaddr.sin_addr;
00836    return AST_SUCCESS;
00837 }

const struct sockaddr_in* sip_real_dst const struct sip_dialog p  ) 
 

The real destination address for a write.

Definition at line 751 of file sip3_network.c.

References ast_test_flag, sip_dialog::flags, sip_dialog::recv, sip_dialog::sa, SIP_NAT, and SIP_NAT_ROUTE.

00752 {
00753    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
00754 }

void sipnet_lock struct sip_network sipnet  ) 
 

Lock netlock.

Lock netlock mutex

Definition at line 120 of file sip3_network.c.

References ast_log(), ast_mutex_lock(), sip_network::lock, LOG_DEBUG, option_debug, sipdebug, and sipnet.

Referenced by process_sip_queue(), sipsock_init(), and sipsock_read().

00121 {
00122    if (option_debug > 3 && sipdebug)
00123       ast_log(LOG_DEBUG, "Locking sipnet :::::::::::::::::\n");
00124    ast_mutex_lock(&sipnet->lock);
00125 }

static void sipnet_lock_init struct sip_network sipnet  )  [static]
 

Initialize network lock.

Definition at line 114 of file sip3_network.c.

References ast_mutex_init().

Referenced by sipsock_init().

00115 {
00116    ast_mutex_init(&sipnet->lock);
00117 }

int sipnet_ourport struct sip_network sipnet  ) 
 

read our port number

Get current port number

Definition at line 466 of file sip3_network.c.

References sip_network::ourport, and sipnet.

Referenced by build_contact(), build_via(), and reload_config().

00467 {
00468    return(sipnet->ourport);
00469 }

void sipnet_ourport_set struct sip_network sipnet,
int  port
 

Set our port number.

Set our port number

Definition at line 472 of file sip3_network.c.

References sip_network::ourport, and sipnet.

Referenced by reload_config(), and reset_ip_interface().

00473 {
00474    sipnet->ourport = port;
00475 }

void sipnet_unlock struct sip_network sipnet  ) 
 

Unlock netlock.

Unlock netlock mutex

Definition at line 128 of file sip3_network.c.

References ast_log(), ast_mutex_unlock(), sip_network::lock, LOG_DEBUG, option_debug, sipdebug, and sipnet.

Referenced by process_sip_queue(), sipsock_init(), and sipsock_read().

00129 {
00130    if (option_debug > 3 && sipdebug)
00131       ast_log(LOG_DEBUG, "Unlocking sipnet :::::::::::::::::\n");
00132    ast_mutex_unlock(&sipnet->lock);
00133 }

struct sip_request* siprequest_alloc size_t  len,
struct sip_network sipnet
 

Allocate SIP request structure.

Parameters:
len The size of the data structure for the actual SIP message on the network - headers and payload
sipnet The socket to use for this request

Definition at line 196 of file sip3_network.c.

References ast_calloc, ast_log(), free, LOG_DEBUG, LOG_WARNING, option_debug, sip_network::req_counter, and sipnet.

Referenced by __transmit_response(), append_send_history(), sipsock_read(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_response_with_attachment(), transmit_response_with_auth(), transmit_response_with_unsupported(), and transmit_state_notify().

00197 {
00198    struct sip_request *req;
00199 
00200    if (len <= 0) {
00201       ast_log(LOG_WARNING, "#### Can't allocate negative or NULL memory for sip_request structure!!!\n");
00202       return NULL;
00203    }
00204    
00205    if (!(req = ast_calloc(1, sizeof(*req)))) {
00206       ast_log(LOG_WARNING, "#### Can't allocate memory for sip_request structure!!!\n");
00207       return NULL;
00208    }
00209 
00210    if (!(req->data = ast_calloc(1, len))) {
00211       ast_log(LOG_WARNING, "#### Can't allocate memory for sip_request data!!!\n");
00212       free(req);
00213       return NULL;
00214    }
00215    req->data_size = len;
00216 
00217    sipnet->req_counter++;
00218 
00219    req->socket = sipnet;
00220 
00221    if (option_debug > 2)
00222       ast_log(LOG_DEBUG, "+++ Allocating SIP request, size %d (Counter #%u)\n", (int) len, sipnet->req_counter);
00223 
00224    return req;
00225 }

void siprequest_free struct sip_request req  ) 
 

Free SIP request.

Definition at line 228 of file sip3_network.c.

References ast_log(), sip_request::data, free, LOG_DEBUG, option_debug, sip_network::req_counter, and sip_request::socket.

Referenced by __sip_ack(), __transmit_response(), append_send_history(), initialize_initreq(), retrans_pkt(), sip_park_thread(), sipsock_read(), transmit_invite(), transmit_request(), transmit_request_with_auth(), transmit_response_with_attachment(), transmit_response_with_auth(), and transmit_response_with_unsupported().

00229 {
00230    req->socket->req_counter--;
00231    if (option_debug > 2)
00232       ast_log(LOG_DEBUG, "--- Deallocating SIP request (Counter now #%u)\n",  req->socket->req_counter);
00233    free(req->data);
00234    free(req);
00235 }

int sipsock_init struct sip_network sipnet,
struct sockaddr_in *  old_bindaddr
 

Initialize IP socket on configured address - the bind address.

Todo:
Needs to be converted to netsock

Definition at line 156 of file sip3_network.c.

References sip_network::__ourip, ast_find_ourip(), ast_log(), sip_network::bindaddr, DEFAULT_LISTEN_SIP_PORT, LOG_DEBUG, LOG_WARNING, option_debug, sipnet, sipnet_lock(), sipnet_lock_init(), sipnet_unlock(), sip_network::sipsock, sipsocket_initialized(), and sipsocket_open().

00157 {
00158    sipnet_lock_init(sipnet);
00159    if (ast_find_ourip(&sipnet->__ourip, sipnet->bindaddr)) {
00160       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
00161       return -1;
00162    }
00163    if (!ntohs(sipnet->bindaddr.sin_port))
00164       sipnet->bindaddr.sin_port = ntohs(DEFAULT_LISTEN_SIP_PORT);
00165    sipnet->bindaddr.sin_family = AF_INET;
00166    sipnet_lock(sipnet);
00167    if (sipsocket_initialized(sipnet) && (memcmp(old_bindaddr, &sipnet->bindaddr, sizeof(struct sockaddr_in)))) {
00168       close(sipnet->sipsock);
00169       sipnet->sipsock = -1;
00170    }
00171    if (!sipsocket_initialized(sipnet)) 
00172       sipsocket_open(sipnet); /* Open socket, bind to address and set TOS option */
00173    ast_log(LOG_DEBUG, "=== SIPNET sipsock_init after open \n");
00174    sipnet_unlock(sipnet);
00175    if (option_debug > 2) {
00176       if (sipnet->sipsock > -1)
00177          ast_log(LOG_DEBUG, "=== SIPNET initialized and ready for business\n");
00178       else
00179          ast_log(LOG_DEBUG, "=== SIPNET initialization failed. SIP3 not ready for business on this socket\n");
00180    }
00181    return 0;
00182 }

int sipsock_read int *  id,
int  fd,
short  events,
void *  ignore
 

Read data from SIP socket.

Note:
sipsock_read locks the owner channel while we are processing the SIP message We read the data into the sipnet structure's buffer (one per socket) and then create the request based on the size of the received data
Returns:
1 on error, 0 on success
Note:
Successful messages is connected to SIP call and forwarded to handle_request()

Definition at line 260 of file sip3_network.c.

References AST_FAILURE, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, ast_verbose(), sip_request::data, find_sip_method(), len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, lws2sws(), sip_network::networkbuf, option_debug, parse_request(), process_sip_queue(), queue_sip_request(), sip_debug_test_addr(), sip_debug_test_level(), SIP_PKT_DEBUG, sipnet, sipnet_lock(), sipnet_unlock(), siprequest_alloc(), siprequest_free(), and sip_network::sipsock.

00261 {
00262    struct sip_request *req;
00263    struct sockaddr_in sin = { 0, };
00264    int res;
00265    socklen_t len;
00266 
00267 
00268    len = sizeof(sin);
00269    //res = recvfrom(sipnet->sipsock, req->data, sizeof(req->data) - 1, 0, (struct sockaddr *)&sin, &len);
00270 
00271    /* Lock sipnet, so we're the only ones using the network buffer for this socket */
00272    sipnet_lock(&sipnet);
00273    res = recvfrom(sipnet.sipsock, sipnet.networkbuf, sizeof(sipnet.networkbuf) - 1, 0, (struct sockaddr *)&sin, &len);
00274    if (res < 0) {
00275       if (option_debug > 3)
00276          ast_log(LOG_DEBUG, "Nothing to read right now... Standing by\n");
00277 #if !defined(__FreeBSD__)
00278       if (errno == EAGAIN)
00279          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
00280       else 
00281 #endif
00282       if (errno != ECONNREFUSED)
00283          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
00284       sipnet_unlock(&sipnet);
00285       return 1;
00286    }
00287    if (option_debug > 4)
00288       ast_log(LOG_DEBUG, "::::::: Received SIP message, size %d\n", res);
00289 
00290    /* Allocate sip request structure sized for this packet */
00291    req = siprequest_alloc((size_t) res + 1, &sipnet);
00292    if (req == NULL) {
00293       ast_log(LOG_ERROR, "Allocation error\n");
00294       sipnet_unlock(&sipnet);
00295       return AST_FAILURE;
00296    }
00297 
00298    /* Copy the network buffer to the allocated request data buffer */
00299    memcpy(req->data, sipnet.networkbuf, res);
00300 
00301 
00302    if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */
00303       ast_set_flag(req, SIP_PKT_DEBUG);
00304 
00305    sipnet.networkbuf[res] = req->data[res] = '\0';
00306 
00307    req->len = lws2sws(req->data, res); /* Fix multiline headers */
00308 
00309 
00310    parse_request(req);
00311    req->method = find_sip_method(req->rlPart1);
00312 
00313    if (ast_test_flag(req, SIP_PKT_DEBUG) && sip_debug_test_level(req->method)) {
00314       ast_verbose("\n<-- SIP read from %s:%d: \n%s\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), sipnet.networkbuf);
00315       ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : "");
00316    }
00317 
00318    /* Release sipnet lock for a while, since we do not need the buffer any more */
00319    sipnet_unlock(&sipnet);
00320 
00321    if (req->headers < 2) {
00322       /* Must have at least two headers */
00323       siprequest_free(req);
00324       return AST_FAILURE;
00325    }
00326    
00327    /* The packet is ready to queue */
00328    queue_sip_request(req, &sin);
00329 
00330    /* For testing, process it quickly */
00331    process_sip_queue();
00332 
00333    return 1;
00334 
00335 }

int sipsocket_initialized struct sip_network sipnet  ) 
 

Check if network socket is open.

Definition at line 421 of file sip3_network.c.

References FALSE, sipnet, sip_network::sipsock, and TRUE.

Referenced by do_sip_monitor(), and sipsock_init().

00422 {
00423    if (sipnet->sipsock < 0)
00424       return FALSE;
00425    return TRUE;
00426 }

int sipsocket_open struct sip_network sipnet  ) 
 

Open network socket, bind to address and set options (TOS).

Definition at line 429 of file sip3_network.c.

References ast_enable_packet_fragmentation(), ast_inet_ntoa(), ast_log(), ast_tos2str(), ast_verbose(), sip_network::bindaddr, FALSE, global, LOG_WARNING, option_verbose, sipnet, sip_network::sipsock, sip_globals::tos_sip, TRUE, and VERBOSE_PREFIX_2.

Referenced by sipsock_init().

00430 {
00431    const int reuseFlag = 1;
00432 
00433 
00434    sipnet->sipsock = socket(AF_INET, SOCK_DGRAM, 0);
00435    if (sipnet->sipsock < 0) {
00436       ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
00437       return FALSE;
00438    } 
00439    /* Allow SIP clients on the same host to access us: */
00440    setsockopt(sipnet->sipsock, SOL_SOCKET, SO_REUSEADDR,
00441                (const char*)&reuseFlag,
00442                sizeof reuseFlag);
00443    
00444    ast_enable_packet_fragmentation(sipnet->sipsock);
00445 
00446    if (bind(sipnet->sipsock, (struct sockaddr *)&sipnet->bindaddr, sizeof(sipnet->bindaddr)) < 0) {
00447       ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
00448          ast_inet_ntoa(sipnet->bindaddr.sin_addr), ntohs(sipnet->bindaddr.sin_port),
00449          strerror(errno));
00450       close(sipnet->sipsock);
00451       sipnet->sipsock = -1;
00452       return FALSE;
00453    } else {
00454       if (setsockopt(sipnet->sipsock, IPPROTO_IP, IP_TOS, &global.tos_sip, sizeof(global.tos_sip))) 
00455          ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global.tos_sip));
00456       else if (option_verbose > 1) { 
00457          ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 
00458             ast_inet_ntoa(sipnet->bindaddr.sin_addr), ntohs(sipnet->bindaddr.sin_port));
00459          ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global.tos_sip));
00460       }
00461    }
00462    return TRUE;
00463 }


Variable Documentation

struct sip_globals global
 

Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.

Global settings only apply to the channel

Definition at line 488 of file chan_sip3.c.

Referenced by __sip_destroy(), _sip_show_device(), add_header(), append_maxforwards(), build_device(), build_rpid(), check_user_full(), create_addr(), create_addr_from_peer(), destroy_association(), dialog_activate_media(), dialogstatechange(), does_peer_need_mwi(), get_also_info(), get_destination(), get_refer_info(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_subscribe(), handle_response_peerpoke(), handle_response_register(), pbx_builtin_setvar(), realtime_update_peer(), register_peer_exten(), register_verify(), reload_config(), reqprep(), reset_global_settings(), respprep(), retrans_pkt(), set_device_defaults(), sip_alloc(), sip_call(), sip_debug_test_level(), sip_do_debug(), sip_do_debug_device(), sip_do_debug_ip(), sip_do_history(), sip_get_rtp_peer(), sip_new(), sip_no_debug(), sip_no_history(), sip_poke_noanswer(), sip_reg_timeout(), sip_show_history(), sip_show_settings(), sipsocket_open(), temp_device(), transmit_notify_with_mwi(), transmit_register(), transmit_response_using_temp(), transmit_response_with_auth(), transmit_state_notify(), and update_peer().

struct sip_network sipnet
 

Sockets and networking

Definition at line 102 of file sip3_network.c.

Referenced by __sip_reliable_xmit(), __sip_xmit(), __transmit_response(), append_send_history(), build_contact(), build_via(), close_sip_sockets(), dialog_activate_media(), do_sip_monitor(), process_sip_queue(), reload_config(), reset_ip_interface(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_debug_test_addr(), sip_do_debug(), sip_do_debug_device(), sip_do_debug_ip(), sip_ouraddrfor(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_settings(), sipnet_lock(), sipnet_ourport(), sipnet_ourport_set(), sipnet_unlock(), siprequest_alloc(), sipsock_init(), sipsock_read(), sipsocket_initialized(), sipsocket_open(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_response_using_temp(), transmit_response_with_attachment(), transmit_response_with_auth(), transmit_response_with_unsupported(), and transmit_state_notify().


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen