summaryrefslogtreecommitdiff
path: root/channels/chan_sip.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r--channels/chan_sip.c78
1 files changed, 45 insertions, 33 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index e68718646..ba5adb7cb 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1960,7 +1960,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 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(struct sip_pvt *dialog, const char *opeer, struct in_addr *sin);
+static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin);
static char *generate_random_string(char *buf, size_t size);
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);
@@ -2529,7 +2529,7 @@ static int __sip_xmit(struct sip_pvt *p, struct ast_str *data, int len)
int res = 0;
const struct sockaddr_in *dst = sip_real_dst(p);
- ast_debug(1, "Trying to put '%.10s' onto %s socket destined for %s\n", data->str, get_transport(p->socket.type), ast_inet_ntoa(dst->sin_addr));
+ ast_debug(1, "Trying to put '%.10s' onto %s socket destined for %s:%d\n", data->str, get_transport(p->socket.type), ast_inet_ntoa(dst->sin_addr), htons(dst->sin_port));
if (sip_prepare_socket(p) < 0)
return XMIT_ERROR;
@@ -4053,11 +4053,10 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
return 0;
}
-
/*! \brief 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 */
-static int create_addr(struct sip_pvt *dialog, const char *opeer, struct in_addr *sin)
+static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin)
{
struct hostent *hp;
struct ast_hostent ahp;
@@ -4096,26 +4095,32 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct in_addr
if (dialog->outboundproxy)
return 0;
- /* Let's see if we can find the host in DNS. First try DNS SRV records,
- then hostname lookup */
- hostn = peername;
- portno = port ? atoi(port) : (dialog->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
- if (global_srvlookup) {
- char service[MAXHOSTNAMELEN];
- int tportno;
+ /* This address should be updated using dnsmgr */
+ if (sin) {
+ memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr));
+ if (!sin->sin_port) {
+ portno = port ? atoi(port) : (dialog->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
+ } else {
+ portno = ntohs(sin->sin_port);
+ }
+ } else {
- snprintf(service, sizeof(service), "_sip._%s.%s", get_transport(dialog->socket.type), peername);
- srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
- if (srv_ret > 0) {
- hostn = host;
- portno = tportno;
+ /* Let's see if we can find the host in DNS. First try DNS SRV records,
+ then hostname lookup */
+ hostn = peername;
+ portno = port ? atoi(port) : (dialog->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
+ if (global_srvlookup) {
+ char service[MAXHOSTNAMELEN];
+ int tportno;
+
+ snprintf(service, sizeof(service), "_sip._%s.%s", get_transport(dialog->socket.type), peername);
+ srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
+ if (srv_ret > 0) {
+ hostn = host;
+ portno = tportno;
+ }
}
- }
- if (sin && srv_ret <= 0) {
- memcpy(&dialog->sa.sin_addr, sin, sizeof(dialog->sa.sin_addr));
- ast_log(LOG_DEBUG, "IP lookup for hostname=%s, using dnsmgr resolved to %s...\n", peername, ast_inet_ntoa(*sin));
- } else {
hp = ast_gethostbyname(hostn, &ahp);
if (!hp) {
ast_log(LOG_WARNING, "No such host: %s\n", peername);
@@ -9221,8 +9226,10 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
}
if (r->dnsmgr == NULL) {
- ast_dnsmgr_lookup(r->hostname, &r->us.sin_addr, &r->dnsmgr);
- }
+ char transport[MAXHOSTNAMELEN];
+ snprintf(transport, sizeof(transport), "_sip._%s", get_transport(r->transport)); /* have to use static get_transport function */
+ ast_dnsmgr_lookup(r->hostname, &r->us, &r->dnsmgr, global_srvlookup ? transport : NULL);
+ }
if (r->call) { /* We have a registration */
if (!auth) {
@@ -9250,8 +9257,12 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
p->outboundproxy = obproxy_get(p, NULL);
+ /* Use port number specified if no SRV record was found */
+ if (!r->us.sin_port && r->portno)
+ r->us.sin_port = htons(r->portno);
+
/* Find address to hostname */
- if (create_addr(p, r->hostname, &r->us.sin_addr)) {
+ if (create_addr(p, r->hostname, &r->us)) {
/* we have what we hope is a temporary network error,
* probably DNS. We need to reschedule a registration try */
sip_destroy(p);
@@ -9265,13 +9276,15 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
r->regattempts++;
return 0;
}
+
/* Copy back Call-ID in case create_addr changed it */
ast_string_field_set(r, callid, p->callid);
- if (r->portno) {
+ if (!r->dnsmgr && r->portno) {
p->sa.sin_port = htons(r->portno);
p->recv.sin_port = htons(r->portno);
- } else /* Set registry port to the port set from the peer definition/srv or default */
+ } else { /* Set registry port to the port set from the peer definition/srv or default */
r->portno = ntohs(p->sa.sin_port);
+ }
ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
r->call = dialog_ref(p); /* Save pointer to SIP dialog */
p->registry = registry_addref(r); /* Add pointer to registry in packet */
@@ -9298,6 +9311,7 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
/* Set transport and port so the correct contact is built */
p->socket.type = r->transport;
p->socket.port = htons(r->portno);
+
/*
check which address we should use in our contact header
based on whether the remote host is on the external or
@@ -20068,13 +20082,11 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
}
}
- if (srvlookup) {
- if (ast_get_ip_or_srv(&peer->addr, srvlookup,
- global_srvlookup ?
- ((peer->socket.type & SIP_TRANSPORT_UDP) ? "_sip._udp" :
- (peer->socket.type & SIP_TRANSPORT_TCP) ? "_sip._tcp" :
- "_sip._tls")
- : NULL)) {
+ if (srvlookup && peer->dnsmgr == NULL) {
+ char transport[MAXHOSTNAMELEN];
+ snprintf(transport, sizeof(transport), "_sip._%s", get_transport(peer->socket.type));
+
+ if (ast_dnsmgr_lookup(srvlookup, &peer->addr, &peer->dnsmgr, global_srvlookup ? transport : NULL)) {
unref_peer(peer);
return NULL;
}