|
|
@ -1950,6 +1950,37 @@ static void peer_mailboxes_to_str(struct ast_str **mailbox_str, struct sip_peer
|
|
|
|
static int sip_refer_allocate(struct sip_pvt *p);
|
|
|
|
static int sip_refer_allocate(struct sip_pvt *p);
|
|
|
|
static void ast_quiet_chan(struct ast_channel *chan);
|
|
|
|
static void ast_quiet_chan(struct ast_channel *chan);
|
|
|
|
static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target);
|
|
|
|
static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
|
|
|
* \brief generic function for determining if a correct transport is being
|
|
|
|
|
|
|
|
* used to contact a peer
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* this is done as a macro so that the "tmpl" var can be passed either a
|
|
|
|
|
|
|
|
* sip_request or a sip_peer
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define check_request_transport(peer, tmpl) ({ \
|
|
|
|
|
|
|
|
int ret = 0; \
|
|
|
|
|
|
|
|
if (peer->socket.type == tmpl->socket.type) \
|
|
|
|
|
|
|
|
; \
|
|
|
|
|
|
|
|
else if (!(peer->transports & tmpl->socket.type)) {\
|
|
|
|
|
|
|
|
ast_log(LOG_ERROR, \
|
|
|
|
|
|
|
|
"'%s' is not a valid transport for '%s'. we only use '%s'! ending call.\n", \
|
|
|
|
|
|
|
|
get_transport(tmpl->socket.type), peer->name, get_transport_list(peer) \
|
|
|
|
|
|
|
|
); \
|
|
|
|
|
|
|
|
ret = 1; \
|
|
|
|
|
|
|
|
} else if (peer->socket.type & SIP_TRANSPORT_TLS) { \
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING, \
|
|
|
|
|
|
|
|
"peer '%s' HAS NOT USED (OR SWITCHED TO) TLS in favor of '%s' (but this was allowed in sip.conf)!\n", \
|
|
|
|
|
|
|
|
peer->name, get_transport(tmpl->socket.type) \
|
|
|
|
|
|
|
|
); \
|
|
|
|
|
|
|
|
} else { \
|
|
|
|
|
|
|
|
ast_debug(1, \
|
|
|
|
|
|
|
|
"peer '%s' has contacted us over %s even though we prefer %s.\n", \
|
|
|
|
|
|
|
|
peer->name, get_transport(tmpl->socket.type), get_transport(peer->socket.type) \
|
|
|
|
|
|
|
|
); \
|
|
|
|
|
|
|
|
}\
|
|
|
|
|
|
|
|
(ret); \
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*--- Device monitoring and Device/extension state/event handling */
|
|
|
|
/*--- Device monitoring and Device/extension state/event handling */
|
|
|
|
static int cb_extensionstate(char *context, char* exten, int state, void *data);
|
|
|
|
static int cb_extensionstate(char *context, char* exten, int state, void *data);
|
|
|
@ -2103,7 +2134,7 @@ static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg
|
|
|
|
static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p);
|
|
|
|
static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p);
|
|
|
|
static void build_via(struct sip_pvt *p);
|
|
|
|
static void build_via(struct sip_pvt *p);
|
|
|
|
static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer);
|
|
|
|
static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer);
|
|
|
|
static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin);
|
|
|
|
static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin, int newdialog);
|
|
|
|
static char *generate_random_string(char *buf, size_t size);
|
|
|
|
static char *generate_random_string(char *buf, size_t size);
|
|
|
|
static void build_callid_pvt(struct sip_pvt *pvt);
|
|
|
|
static void build_callid_pvt(struct sip_pvt *pvt);
|
|
|
|
static void build_callid_registry(struct sip_registry *reg, struct in_addr ourip, const char *fromdomain);
|
|
|
|
static void build_callid_registry(struct sip_registry *reg, struct in_addr ourip, const char *fromdomain);
|
|
|
@ -4135,6 +4166,11 @@ static void copy_socket_data(struct sip_socket *to_sock, const struct sip_socket
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
|
|
|
|
static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
/* this checks that the dialog is contacting the peer on a valid
|
|
|
|
|
|
|
|
* transport type based on the peers transport configuration,
|
|
|
|
|
|
|
|
* otherwise, this function bails out */
|
|
|
|
|
|
|
|
if (dialog->socket.type && check_request_transport(peer, dialog))
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
copy_socket_data(&dialog->socket, &peer->socket);
|
|
|
|
copy_socket_data(&dialog->socket, &peer->socket);
|
|
|
|
|
|
|
|
|
|
|
|
if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
|
|
|
|
if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
|
|
|
@ -4260,10 +4296,11 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*! \brief create address structure from device name
|
|
|
|
/*! \brief create address structure from device name
|
|
|
|
* Or, if peer not found, find it in the global DNS
|
|
|
|
* Or, if peer not found, find it in the global DNS
|
|
|
|
* returns TRUE (-1) on failure, FALSE on success */
|
|
|
|
* returns TRUE (-1) on failure, FALSE on success */
|
|
|
|
static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin)
|
|
|
|
static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin, int newdialog)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct hostent *hp;
|
|
|
|
struct hostent *hp;
|
|
|
|
struct ast_hostent ahp;
|
|
|
|
struct ast_hostent ahp;
|
|
|
@ -4284,13 +4321,12 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
|
|
|
|
peer = find_peer(peername, NULL, TRUE, TRUE);
|
|
|
|
peer = find_peer(peername, NULL, TRUE, TRUE);
|
|
|
|
|
|
|
|
|
|
|
|
if (peer) {
|
|
|
|
if (peer) {
|
|
|
|
int res = create_addr_from_peer(dialog, peer);
|
|
|
|
int res;
|
|
|
|
|
|
|
|
if (newdialog)
|
|
|
|
|
|
|
|
dialog->socket.type = 0;
|
|
|
|
|
|
|
|
res = create_addr_from_peer(dialog, peer);
|
|
|
|
unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup");
|
|
|
|
unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup");
|
|
|
|
return res;
|
|
|
|
return res;
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/* Setup default parameters for this dialog's socket. Currently we only support regular UDP SIP as the default */
|
|
|
|
|
|
|
|
dialog->socket.type = SIP_TRANSPORT_UDP;
|
|
|
|
|
|
|
|
dialog->socket.port = bindaddr.sin_port;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ast_string_field_set(dialog, tohost, peername);
|
|
|
|
ast_string_field_set(dialog, tohost, peername);
|
|
|
@ -4306,7 +4342,10 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
|
|
|
|
if (sin) {
|
|
|
|
if (sin) {
|
|
|
|
memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr));
|
|
|
|
memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr));
|
|
|
|
if (!sin->sin_port) {
|
|
|
|
if (!sin->sin_port) {
|
|
|
|
portno = port ? atoi(port) : (dialog->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
|
|
|
|
if (ast_strlen_zero(port) || sscanf(port, "%u", &portno) != 1) {
|
|
|
|
|
|
|
|
portno = dialog->socket.type & SIP_TRANSPORT_TLS ?
|
|
|
|
|
|
|
|
STANDARD_TLS_PORT : STANDARD_SIP_PORT;
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
portno = ntohs(sin->sin_port);
|
|
|
|
portno = ntohs(sin->sin_port);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -4339,6 +4378,8 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
|
|
|
|
memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
|
|
|
|
memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!dialog->socket.type)
|
|
|
|
|
|
|
|
dialog->socket.type = SIP_TRANSPORT_UDP;
|
|
|
|
dialog->sa.sin_port = htons(portno);
|
|
|
|
dialog->sa.sin_port = htons(portno);
|
|
|
|
dialog->recv = dialog->sa;
|
|
|
|
dialog->recv = dialog->sa;
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
@ -4406,7 +4447,6 @@ static int sip_call(struct ast_channel *ast, char *dest, int timeout)
|
|
|
|
p->t38.state = T38_LOCAL_DIRECT;
|
|
|
|
p->t38.state = T38_LOCAL_DIRECT;
|
|
|
|
ast_debug(1, "T38State change to %d on channel %s\n", p->t38.state, ast->name);
|
|
|
|
ast_debug(1, "T38State change to %d on channel %s\n", p->t38.state, ast->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
res = 0;
|
|
|
|
res = 0;
|
|
|
@ -9442,7 +9482,7 @@ static int manager_sipnotify(struct mansession *s, const struct message *m)
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (create_addr(p, channame, NULL)) {
|
|
|
|
if (create_addr(p, channame, NULL, 0)) {
|
|
|
|
/* Maybe they're not registered, etc. */
|
|
|
|
/* Maybe they're not registered, etc. */
|
|
|
|
dialog_unlink_all(p, TRUE, TRUE);
|
|
|
|
dialog_unlink_all(p, TRUE, TRUE);
|
|
|
|
dialog_unref(p, "unref dialog inside for loop" );
|
|
|
|
dialog_unref(p, "unref dialog inside for loop" );
|
|
|
@ -9654,7 +9694,7 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
|
|
|
|
r->us.sin_port = htons(r->portno);
|
|
|
|
r->us.sin_port = htons(r->portno);
|
|
|
|
|
|
|
|
|
|
|
|
/* Find address to hostname */
|
|
|
|
/* Find address to hostname */
|
|
|
|
if (create_addr(p, r->hostname, &r->us)) {
|
|
|
|
if (create_addr(p, r->hostname, &r->us, 0)) {
|
|
|
|
/* we have what we hope is a temporary network error,
|
|
|
|
/* we have what we hope is a temporary network error,
|
|
|
|
* probably DNS. We need to reschedule a registration try */
|
|
|
|
* probably DNS. We need to reschedule a registration try */
|
|
|
|
dialog_unlink_all(p, TRUE, TRUE);
|
|
|
|
dialog_unlink_all(p, TRUE, TRUE);
|
|
|
@ -10852,27 +10892,10 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (peer->socket.type != req->socket.type ) {
|
|
|
|
if (check_request_transport(peer, req)) {
|
|
|
|
if (!(peer->transports & req->socket.type)) {
|
|
|
|
ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
|
|
|
|
ast_log(LOG_ERROR,
|
|
|
|
transmit_response_with_date(p, "403 Forbidden", req);
|
|
|
|
"peer '%s' has contacted us over %s, but we only accept '%s' for this peer! ending call.\n",
|
|
|
|
res = AUTH_BAD_TRANSPORT;
|
|
|
|
peer->name, get_transport(req->socket.type), get_transport_list(peer)
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
|
|
|
|
|
|
|
|
transmit_response_with_date(p, "403 Forbidden", req);
|
|
|
|
|
|
|
|
res = AUTH_BAD_TRANSPORT;
|
|
|
|
|
|
|
|
} else if (peer->socket.type & SIP_TRANSPORT_TLS) {
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING,
|
|
|
|
|
|
|
|
"peer '%s' HAS STOPPED USING TLS in favor of '%s' (but this was allowed in sip.conf)!\n",
|
|
|
|
|
|
|
|
peer->name, get_transport(req->socket.type)
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
ast_log(LOG_DEBUG,
|
|
|
|
|
|
|
|
"peer '%s' has contacted us over %s even though we prefer %s.\n",
|
|
|
|
|
|
|
|
peer->name, get_transport(req->socket.type), get_transport(peer->socket.type)
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -14423,7 +14446,7 @@ static char *sip_cli_notify(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
|
|
|
|
return CLI_FAILURE;
|
|
|
|
return CLI_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (create_addr(p, a->argv[i], NULL)) {
|
|
|
|
if (create_addr(p, a->argv[i], NULL, 0)) {
|
|
|
|
/* Maybe they're not registered, etc. */
|
|
|
|
/* Maybe they're not registered, etc. */
|
|
|
|
dialog_unlink_all(p, TRUE, TRUE);
|
|
|
|
dialog_unlink_all(p, TRUE, TRUE);
|
|
|
|
dialog_unref(p, "unref dialog inside for loop" );
|
|
|
|
dialog_unref(p, "unref dialog inside for loop" );
|
|
|
@ -14996,13 +15019,41 @@ static struct ast_custom_function sipchaninfo_function = {
|
|
|
|
static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req)
|
|
|
|
static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
char tmp[SIPBUFSIZE];
|
|
|
|
char tmp[SIPBUFSIZE];
|
|
|
|
char *s, *e, *t;
|
|
|
|
char *s, *e, *t, *trans;
|
|
|
|
char *domain;
|
|
|
|
char *domain;
|
|
|
|
|
|
|
|
enum sip_transport transport = SIP_TRANSPORT_UDP;
|
|
|
|
|
|
|
|
|
|
|
|
ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
|
|
|
|
ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
|
|
|
|
if ((t = strchr(tmp, ',')))
|
|
|
|
if ((t = strchr(tmp, ',')))
|
|
|
|
*t = '\0';
|
|
|
|
*t = '\0';
|
|
|
|
s = remove_uri_parameters(get_in_brackets(tmp));
|
|
|
|
|
|
|
|
|
|
|
|
s = get_in_brackets(tmp);
|
|
|
|
|
|
|
|
if ((trans = strcasestr(s, ";transport="))) do {
|
|
|
|
|
|
|
|
trans += 11;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((e = strchr(trans, ';')))
|
|
|
|
|
|
|
|
*e = '\0';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!strncasecmp(trans, "tcp", 3))
|
|
|
|
|
|
|
|
transport = SIP_TRANSPORT_TCP;
|
|
|
|
|
|
|
|
else if (!strncasecmp(trans, "tls", 3))
|
|
|
|
|
|
|
|
transport = SIP_TRANSPORT_TLS;
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
if (strncasecmp(trans, "udp", 3))
|
|
|
|
|
|
|
|
ast_debug(1, "received contact with an invalid transport, '%s'\n", s);
|
|
|
|
|
|
|
|
transport = SIP_TRANSPORT_UDP;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} while(0);
|
|
|
|
|
|
|
|
s = remove_uri_parameters(s);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (p->socket.ser) {
|
|
|
|
|
|
|
|
ao2_ref(p->socket.ser, -1);
|
|
|
|
|
|
|
|
p->socket.ser = NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p->socket.fd = -1;
|
|
|
|
|
|
|
|
p->socket.type = transport;
|
|
|
|
|
|
|
|
|
|
|
|
if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
|
|
|
|
if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
|
|
|
|
if (!strncasecmp(s, "sip:", 4))
|
|
|
|
if (!strncasecmp(s, "sip:", 4))
|
|
|
|
s += 4;
|
|
|
|
s += 4;
|
|
|
@ -15011,9 +15062,9 @@ static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req)
|
|
|
|
e = strchr(s, '/');
|
|
|
|
e = strchr(s, '/');
|
|
|
|
if (e)
|
|
|
|
if (e)
|
|
|
|
*e = '\0';
|
|
|
|
*e = '\0';
|
|
|
|
ast_debug(2, "Found promiscuous redirection to 'SIP/%s'\n", s);
|
|
|
|
ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", get_transport(transport), s);
|
|
|
|
if (p->owner)
|
|
|
|
if (p->owner)
|
|
|
|
ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
|
|
|
|
ast_string_field_build(p->owner, call_forward, "SIP/::::%s@%s", get_transport(transport), s);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
e = strchr(tmp, '@');
|
|
|
|
e = strchr(tmp, '@');
|
|
|
|
if (e) {
|
|
|
|
if (e) {
|
|
|
@ -17095,7 +17146,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
|
|
|
|
if ((peerorhost = strchr(uri, ':'))) {
|
|
|
|
if ((peerorhost = strchr(uri, ':'))) {
|
|
|
|
*peerorhost++ = '\0';
|
|
|
|
*peerorhost++ = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
create_addr(p, peerorhost, NULL);
|
|
|
|
create_addr(p, peerorhost, NULL, 0);
|
|
|
|
ast_string_field_set(p, theirtag, NULL);
|
|
|
|
ast_string_field_set(p, theirtag, NULL);
|
|
|
|
for (pkt = p->packets; pkt; pkt = pkt->next) {
|
|
|
|
for (pkt = p->packets; pkt; pkt = pkt->next) {
|
|
|
|
if (pkt->seqno == p->icseq && pkt->method == SIP_INVITE) {
|
|
|
|
if (pkt->seqno == p->icseq && pkt->method == SIP_INVITE) {
|
|
|
@ -20068,6 +20119,8 @@ static struct ast_channel *sip_request_call(const char *type, int format, void *
|
|
|
|
char *secret = NULL;
|
|
|
|
char *secret = NULL;
|
|
|
|
char *md5secret = NULL;
|
|
|
|
char *md5secret = NULL;
|
|
|
|
char *authname = NULL;
|
|
|
|
char *authname = NULL;
|
|
|
|
|
|
|
|
char *trans = NULL;
|
|
|
|
|
|
|
|
enum sip_transport transport = 0;
|
|
|
|
int oldformat = format;
|
|
|
|
int oldformat = format;
|
|
|
|
|
|
|
|
|
|
|
|
/* mask request with some set of allowed formats.
|
|
|
|
/* mask request with some set of allowed formats.
|
|
|
@ -20119,29 +20172,48 @@ static struct ast_channel *sip_request_call(const char *type, int format, void *
|
|
|
|
*host++ = '\0';
|
|
|
|
*host++ = '\0';
|
|
|
|
ext = tmp;
|
|
|
|
ext = tmp;
|
|
|
|
secret = strchr(ext, ':');
|
|
|
|
secret = strchr(ext, ':');
|
|
|
|
if (secret) {
|
|
|
|
}
|
|
|
|
*secret++ = '\0';
|
|
|
|
if (secret) {
|
|
|
|
md5secret = strchr(secret, ':');
|
|
|
|
*secret++ = '\0';
|
|
|
|
if (md5secret) {
|
|
|
|
md5secret = strchr(secret, ':');
|
|
|
|
*md5secret++ = '\0';
|
|
|
|
}
|
|
|
|
authname = strchr(md5secret, ':');
|
|
|
|
if (md5secret) {
|
|
|
|
if (authname)
|
|
|
|
*md5secret++ = '\0';
|
|
|
|
*authname++ = '\0';
|
|
|
|
authname = strchr(md5secret, ':');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (authname) {
|
|
|
|
|
|
|
|
*authname++ = '\0';
|
|
|
|
|
|
|
|
trans = strchr(authname, ':');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (trans) {
|
|
|
|
|
|
|
|
*trans++ = '\0';
|
|
|
|
|
|
|
|
if (!strcasecmp(trans, "tcp"))
|
|
|
|
|
|
|
|
transport = SIP_TRANSPORT_TCP;
|
|
|
|
|
|
|
|
else if (!strcasecmp(trans, "tls"))
|
|
|
|
|
|
|
|
transport = SIP_TRANSPORT_TLS;
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
if (strcasecmp(trans, "udp"))
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans);
|
|
|
|
|
|
|
|
transport = SIP_TRANSPORT_UDP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!host) {
|
|
|
|
ext = strchr(tmp, '/');
|
|
|
|
ext = strchr(tmp, '/');
|
|
|
|
if (ext)
|
|
|
|
if (ext)
|
|
|
|
*ext++ = '\0';
|
|
|
|
*ext++ = '\0';
|
|
|
|
host = tmp;
|
|
|
|
host = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p->socket.fd = -1;
|
|
|
|
|
|
|
|
p->socket.type = transport;
|
|
|
|
|
|
|
|
|
|
|
|
/* We now have
|
|
|
|
/* We now have
|
|
|
|
host = peer name, DNS host name or DNS domain (for SRV)
|
|
|
|
host = peer name, DNS host name or DNS domain (for SRV)
|
|
|
|
ext = extension (user part of URI)
|
|
|
|
ext = extension (user part of URI)
|
|
|
|
dnid = destination of the call (applies to the To: header)
|
|
|
|
dnid = destination of the call (applies to the To: header)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if (create_addr(p, host, NULL)) {
|
|
|
|
if (create_addr(p, host, NULL, 1)) {
|
|
|
|
*cause = AST_CAUSE_UNREGISTERED;
|
|
|
|
*cause = AST_CAUSE_UNREGISTERED;
|
|
|
|
ast_debug(3, "Cant create SIP call - target device not registred\n");
|
|
|
|
ast_debug(3, "Cant create SIP call - target device not registred\n");
|
|
|
|
dialog_unlink_all(p, TRUE, TRUE);
|
|
|
|
dialog_unlink_all(p, TRUE, TRUE);
|
|
|
|