summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_gtalk.c35
-rw-r--r--channels/chan_h323.c63
-rw-r--r--channels/chan_iax2.c30
-rw-r--r--channels/chan_jingle.c25
-rw-r--r--channels/chan_mgcp.c73
-rw-r--r--channels/chan_multicast_rtp.c9
-rw-r--r--channels/chan_sip.c1858
-rw-r--r--channels/chan_skinny.c28
-rw-r--r--channels/chan_unistim.c12
-rw-r--r--channels/sip/dialplan_functions.c31
-rw-r--r--channels/sip/include/dialog.h2
-rw-r--r--channels/sip/include/globals.h2
-rw-r--r--channels/sip/include/reqresp_parser.h14
-rw-r--r--channels/sip/include/sip.h27
-rw-r--r--channels/sip/reqresp_parser.c244
15 files changed, 1372 insertions, 1081 deletions
diff --git a/channels/chan_gtalk.c b/channels/chan_gtalk.c
index 252e3fe20..1a964e75a 100644
--- a/channels/chan_gtalk.c
+++ b/channels/chan_gtalk.c
@@ -774,8 +774,10 @@ static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, ch
struct aji_client *c = client->connection;
struct gtalk_candidate *ours1 = NULL, *ours2 = NULL;
struct sockaddr_in sin = { 0, };
+ struct ast_sockaddr sin_tmp;
+ struct ast_sockaddr bindaddr_tmp;
struct sockaddr_in dest;
- struct in_addr us;
+ struct ast_sockaddr us;
iks *iq, *gtalk, *candidate, *transport;
char user[17], pass[17], preference[5], port[7];
char *lowerfrom = NULL;
@@ -809,9 +811,11 @@ static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, ch
goto safeout;
}
- ast_rtp_instance_get_local_address(p->rtp, &sin);
- ast_find_ourip(&us, bindaddr);
- if (!strcmp(ast_inet_ntoa(us), "127.0.0.1")) {
+ ast_rtp_instance_get_local_address(p->rtp, &sin_tmp);
+ ast_sockaddr_to_sin(&sin_tmp, &sin);
+ bindaddr_tmp = ast_sockaddr_from_sin(bindaddr);
+ ast_find_ourip(&us, &bindaddr_tmp);
+ if (!strcmp(ast_sockaddr_stringify_addr(&us), "127.0.0.1")) {
ast_log(LOG_WARNING, "Found a loopback IP on the system, check your network configuration or set the bindaddr attribute.");
}
@@ -823,7 +827,8 @@ static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, ch
snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random());
ast_copy_string(ours1->username, user, sizeof(ours1->username));
ast_copy_string(ours1->password, pass, sizeof(ours1->password));
- ast_copy_string(ours1->ip, ast_inet_ntoa(us), sizeof(ours1->ip));
+ ast_copy_string(ours1->ip, ast_sockaddr_stringify_addr(&us),
+ sizeof(ours1->ip));
ours1->protocol = AJI_PROTOCOL_UDP;
ours1->type = AJI_CONNECT_LOCAL;
ours1->generation = 0;
@@ -911,6 +916,7 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const
struct aji_buddy *buddy;
char idroster[200];
char *data, *exten = NULL;
+ struct ast_sockaddr bindaddr_tmp;
ast_debug(1, "The client is %s for alloc\n", client->name);
if (!sid && !strchr(them, '/')) { /* I started call! */
@@ -950,7 +956,8 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const
tmp->initiator = 1;
}
/* clear codecs */
- if (!(tmp->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr, NULL))) {
+ bindaddr_tmp = ast_sockaddr_from_sin(bindaddr);
+ if (!(tmp->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL))) {
ast_log(LOG_ERROR, "Failed to create a new RTP instance (possibly an invalid bindaddr?)\n");
ast_free(tmp);
return NULL;
@@ -1263,6 +1270,8 @@ static int gtalk_update_stun(struct gtalk *client, struct gtalk_pvt *p)
struct ast_hostent ahp;
struct sockaddr_in sin = { 0, };
struct sockaddr_in aux = { 0, };
+ struct ast_sockaddr sin_tmp;
+ struct ast_sockaddr aux_tmp;
if (time(NULL) == p->laststun)
return 0;
@@ -1281,16 +1290,17 @@ static int gtalk_update_stun(struct gtalk *client, struct gtalk_pvt *p)
p->ourcandidates->username);
/* Find out the result of the STUN */
- ast_rtp_instance_get_remote_address(p->rtp, &aux);
+ ast_rtp_instance_get_remote_address(p->rtp, &aux_tmp);
+ ast_sockaddr_to_sin(&aux_tmp, &aux);
/* If the STUN result is different from the IP of the hostname,
lock on the stun IP of the hostname advertised by the
remote client */
if (aux.sin_addr.s_addr &&
aux.sin_addr.s_addr != sin.sin_addr.s_addr)
- ast_rtp_instance_stun_request(p->rtp, &aux, username);
+ ast_rtp_instance_stun_request(p->rtp, &aux_tmp, username);
else
- ast_rtp_instance_stun_request(p->rtp, &sin, username);
+ ast_rtp_instance_stun_request(p->rtp, &sin_tmp, username);
if (aux.sin_addr.s_addr) {
ast_debug(4, "Receiving RTP traffic from IP %s, matches with remote candidate's IP %s\n", ast_inet_ntoa(aux.sin_addr), tmp->ip);
@@ -2057,6 +2067,9 @@ static int gtalk_load_config(void)
/*! \brief Load module into PBX, register channel */
static int load_module(void)
{
+ struct ast_sockaddr bindaddr_tmp;
+ struct ast_sockaddr ourip_tmp;
+
char *jabber_loaded = ast_module_helper("", "res_jabber.so", 0, 0, 0, 0);
free(jabber_loaded);
if (!jabber_loaded) {
@@ -2083,10 +2096,12 @@ static int load_module(void)
if (!io)
ast_log(LOG_WARNING, "Unable to create I/O context\n");
- if (ast_find_ourip(&__ourip, bindaddr)) {
+ bindaddr_tmp = ast_sockaddr_from_sin(bindaddr);
+ if (ast_find_ourip(&ourip_tmp, &bindaddr_tmp)) {
ast_log(LOG_WARNING, "Unable to get own IP address, Gtalk disabled\n");
return 0;
}
+ __ourip.s_addr = htonl(ast_sockaddr_ipv4(&ourip_tmp));
ast_rtp_glue_register(&gtalk_rtp_glue);
ast_cli_register_multiple(gtalk_cli, ARRAY_LEN(gtalk_cli));
diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index 10234199a..cf41acc69 100644
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -954,15 +954,20 @@ static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
static int __oh323_rtp_create(struct oh323_pvt *pvt)
{
- struct sockaddr_in our_addr;
+ struct ast_sockaddr our_addr;
if (pvt->rtp)
return 0;
- if (ast_find_ourip(&our_addr.sin_addr, bindaddr)) {
- ast_mutex_unlock(&pvt->lock);
- ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n");
- return -1;
+ {
+ struct ast_sockaddr tmp;
+
+ tmp = ast_sockaddr_from_sin(bindaddr);
+ if (ast_find_ourip(&our_addr, &tmp)) {
+ ast_mutex_unlock(&pvt->lock);
+ ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n");
+ return -1;
+ }
}
pvt->rtp = ast_rtp_instance_new("asterisk", sched, &our_addr, NULL);
if (!pvt->rtp) {
@@ -1408,9 +1413,14 @@ static struct oh323_user *build_user(const char *name, struct ast_variable *v, s
ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n");
ASTOBJ_UNREF(user, oh323_destroy_user);
return NULL;
- } else if (ast_get_ip(&user->addr, v->value)) {
- ASTOBJ_UNREF(user, oh323_destroy_user);
- return NULL;
+ } else {
+ struct ast_sockaddr tmp;
+
+ if (ast_get_ip(&tmp, v->value)) {
+ ASTOBJ_UNREF(user, oh323_destroy_user);
+ return NULL;
+ }
+ ast_sockaddr_to_sin(&tmp, &user->addr);
}
/* Let us know we need to use ip authentication */
user->host = 1;
@@ -1522,10 +1532,15 @@ static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, s
ASTOBJ_UNREF(peer, oh323_destroy_peer);
return NULL;
}
- if (ast_get_ip(&peer->addr, v->value)) {
- ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value);
- ASTOBJ_UNREF(peer, oh323_destroy_peer);
- return NULL;
+ {
+ struct ast_sockaddr tmp;
+
+ if (ast_get_ip(&tmp, v->value)) {
+ ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value);
+ ASTOBJ_UNREF(peer, oh323_destroy_peer);
+ return NULL;
+ }
+ ast_sockaddr_to_sin(&tmp, &peer->addr);
}
} else if (!strcasecmp(v->name, "port")) {
peer->addr.sin_port = htons(atoi(v->value));
@@ -1922,7 +1937,12 @@ static struct rtp_info *external_rtp_create(unsigned call_reference, const char
return NULL;
}
/* figure out our local RTP port and tell the H.323 stack about it */
- ast_rtp_instance_get_local_address(pvt->rtp, &us);
+ {
+ struct ast_sockaddr tmp;
+
+ ast_rtp_instance_get_local_address(pvt->rtp, &tmp);
+ ast_sockaddr_to_sin(&tmp, &us);
+ }
ast_mutex_unlock(&pvt->lock);
ast_copy_string(info->addr, ast_inet_ntoa(us.sin_addr), sizeof(info->addr));
@@ -1971,7 +1991,12 @@ static void setup_rtp_connection(unsigned call_reference, const char *remoteIp,
them.sin_port = htons(remotePort);
if (them.sin_addr.s_addr) {
- ast_rtp_instance_set_remote_address(pvt->rtp, &them);
+ {
+ struct ast_sockaddr tmp;
+
+ tmp = ast_sockaddr_from_sin(them);
+ ast_rtp_instance_set_remote_address(pvt->rtp, &tmp);
+ }
if (pvt->recvonly) {
pvt->recvonly = 0;
rtp_change = NEED_UNHOLD;
@@ -3204,8 +3229,14 @@ static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance
ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
return -1;
}
- ast_rtp_instance_get_remote_address(rtp, &them);
- ast_rtp_instance_get_local_address(rtp, &us);
+ {
+ struct ast_sockaddr tmp;
+
+ ast_rtp_instance_get_remote_address(rtp, &tmp);
+ ast_sockaddr_to_sin(&tmp, &them);
+ ast_rtp_instance_get_local_address(rtp, &tmp);
+ ast_sockaddr_to_sin(&tmp, &us);
+ }
#if 0 /* Native bridge still isn't ready */
h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(them.sin_addr), mode);
#endif
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index ba482a065..7880e719d 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -4441,11 +4441,15 @@ static int create_addr(const char *peername, struct ast_channel *c, struct socka
sin->sin_family = AF_INET;
if (!(peer = find_peer(peername, 1))) {
+ struct ast_sockaddr sin_tmp;
+
cai->found = 0;
- if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
+ sin_tmp.ss.ss_family = AF_INET;
+ if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
ast_log(LOG_WARNING, "No such host: %s\n", peername);
return -1;
}
+ ast_sockaddr_to_sin(&sin_tmp, sin);
sin->sin_port = htons(IAX_DEFAULT_PORTNO);
/* use global iax prefs for unknown peer/user */
/* But move the calling channel's native codec to the top of the preference list */
@@ -8312,14 +8316,18 @@ static int iax2_append_register(const char *hostname, const char *username,
const char *secret, const char *porta)
{
struct iax2_registry *reg;
+ struct ast_sockaddr reg_addr_tmp;
if (!(reg = ast_calloc(1, sizeof(*reg))))
return -1;
- if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
+ reg->addr.sin_family = AF_INET;
+ ast_sockaddr_from_sin(&reg_addr_tmp, &reg->addr);
+ if (ast_dnsmgr_lookup(hostname, &reg_addr_tmp, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
ast_free(reg);
return -1;
}
+ ast_sockaddr_to_sin(&reg_addr_tmp, &reg->addr);
ast_copy_string(reg->username, username, sizeof(reg->username));
@@ -11991,6 +11999,7 @@ static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
{
struct sockaddr_in sin;
+ struct ast_sockaddr sin_tmp;
int nonlocal = 1;
int port = IAX_DEFAULT_PORTNO;
int sockfd = defaultsockfd;
@@ -12010,10 +12019,11 @@ static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
port = IAX_DEFAULT_PORTNO;
}
- if (!ast_get_ip(&sin, addr)) {
+ if (!ast_get_ip(&sin_tmp, addr)) {
struct ast_netsock *sock;
int res;
+ ast_sockaddr_to_sin(&sin_tmp, &sin);
sin.sin_port = 0;
sin.sin_family = AF_INET;
res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
@@ -12212,19 +12222,29 @@ static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, st
}
}
} else {
+ struct ast_sockaddr peer_addr_tmp;
+
/* Non-dynamic. Make sure we become that way if we're not */
ast_sched_thread_del(sched, peer->expire);
ast_clear_flag64(peer, IAX_DYNAMIC);
- if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
+ peer_addr_tmp.ss.ss_family = AF_INET;
+ if (ast_dnsmgr_lookup(v->value, &peer_addr_tmp, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
return peer_unref(peer);
+ ast_sockaddr_to_sin(&peer_addr_tmp,
+ &peer->addr);
if (!peer->addr.sin_port)
peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
}
if (!maskfound)
inet_aton("255.255.255.255", &peer->mask);
} else if (!strcasecmp(v->name, "defaultip")) {
- if (ast_get_ip(&peer->defaddr, v->value))
+ struct ast_sockaddr peer_defaddr_tmp;
+
+ if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
return peer_unref(peer);
+ }
+ ast_sockaddr_to_sin(&peer_defaddr_tmp,
+ &peer->defaddr);
} else if (!strcasecmp(v->name, "sourceaddress")) {
peer_set_srcaddr(peer, v->value);
} else if (!strcasecmp(v->name, "permit") ||
diff --git a/channels/chan_jingle.c b/channels/chan_jingle.c
index b876dfd0d..35618b1fa 100644
--- a/channels/chan_jingle.c
+++ b/channels/chan_jingle.c
@@ -581,6 +581,9 @@ static int jingle_create_candidates(struct jingle *client, struct jingle_pvt *p,
struct aji_client *c = client->connection;
struct jingle_candidate *ours1 = NULL, *ours2 = NULL;
struct sockaddr_in sin = { 0, };
+ struct ast_sockaddr sin_tmp;
+ struct ast_sockaddr us_tmp;
+ struct ast_sockaddr bindaddr_tmp;
struct sockaddr_in dest;
struct in_addr us;
struct in_addr externaddr;
@@ -617,8 +620,11 @@ static int jingle_create_candidates(struct jingle *client, struct jingle_pvt *p,
goto safeout;
}
- ast_rtp_instance_get_local_address(p->rtp, &sin);
- ast_find_ourip(&us, bindaddr);
+ ast_rtp_instance_get_local_address(p->rtp, &sin_tmp);
+ ast_sockaddr_to_sin(&sin_tmp, &sin);
+ bindaddr_tmp = ast_sockaddr_from_sin(bindaddr);
+ ast_find_ourip(&us_tmp, &bindaddr_tmp);
+ us.s_addr = htonl(ast_sockaddr_ipv4(&us_tmp));
/* Setup our first jingle candidate */
ours1->component = 1;
@@ -739,6 +745,7 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from,
struct aji_resource *resources = NULL;
struct aji_buddy *buddy;
char idroster[200];
+ struct ast_sockaddr bindaddr_tmp;
ast_debug(1, "The client is %s for alloc\n", client->name);
if (!sid && !strchr(from, '/')) { /* I started call! */
@@ -775,7 +782,8 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from,
ast_copy_string(tmp->them, idroster, sizeof(tmp->them));
tmp->initiator = 1;
}
- tmp->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr, NULL);
+ bindaddr_tmp = ast_sockaddr_from_sin(bindaddr);
+ tmp->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
tmp->parent = client;
if (!tmp->rtp) {
ast_log(LOG_WARNING, "Out of RTP sessions?\n");
@@ -1061,6 +1069,7 @@ static int jingle_update_stun(struct jingle *client, struct jingle_pvt *p)
struct hostent *hp;
struct ast_hostent ahp;
struct sockaddr_in sin;
+ struct ast_sockaddr sin_tmp;
if (time(NULL) == p->laststun)
return 0;
@@ -1075,7 +1084,8 @@ static int jingle_update_stun(struct jingle *client, struct jingle_pvt *p)
sin.sin_port = htons(tmp->port);
snprintf(username, sizeof(username), "%s:%s", tmp->ufrag, p->ourcandidates->ufrag);
- ast_rtp_instance_stun_request(p->rtp, &sin, username);
+ sin_tmp = ast_sockaddr_from_sin(sin);
+ ast_rtp_instance_stun_request(p->rtp, &sin_tmp, username);
tmp = tmp->next;
}
return 1;
@@ -1867,6 +1877,9 @@ static int jingle_load_config(void)
/*! \brief Load module into PBX, register channel */
static int load_module(void)
{
+ struct ast_sockaddr ourip_tmp;
+ struct ast_sockaddr bindaddr_tmp;
+
char *jabber_loaded = ast_module_helper("", "res_jabber.so", 0, 0, 0, 0);
free(jabber_loaded);
if (!jabber_loaded) {
@@ -1893,10 +1906,12 @@ static int load_module(void)
if (!io)
ast_log(LOG_WARNING, "Unable to create I/O context\n");
- if (ast_find_ourip(&__ourip, bindaddr)) {
+ bindaddr_tmp = ast_sockaddr_from_sin(bindaddr);
+ if (ast_find_ourip(&ourip_tmp, &bindaddr_tmp)) {
ast_log(LOG_WARNING, "Unable to get own IP address, Jingle disabled\n");
return 0;
}
+ __ourip.s_addr = htonl(ast_sockaddr_ipv4(&ourip_tmp));
ast_rtp_glue_register(&jingle_rtp_glue);
ast_cli_register_multiple(jingle_cli, ARRAY_LEN(jingle_cli));
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index 420bc51a8..63dcb936d 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -1769,8 +1769,19 @@ static struct mgcp_subchannel *find_subchannel_and_lock(char *name, int msgid, s
if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
(g->addr.sin_port != sin->sin_port)) {
memcpy(&g->addr, sin, sizeof(g->addr));
- if (ast_ouraddrfor(&g->addr.sin_addr, &g->ourip))
- memcpy(&g->ourip, &__ourip, sizeof(g->ourip));
+ {
+ struct ast_sockaddr tmp1, tmp2;
+ struct sockaddr_in tmp3 = {0,};
+
+ tmp3.sin_addr = g->ourip;
+ ast_sockaddr_from_sin(&tmp1, &g->addr);
+ ast_sockaddr_from_sin(&tmp2, &tmp3);
+ if (ast_ouraddrfor(&tmp1, &tmp2)) {
+ memcpy(&g->ourip, &__ourip, sizeof(g->ourip));
+ }
+ ast_sockaddr_to_sin(&tmp2, &tmp3);
+ g->ourip = tmp3.sin_addr;
+ }
ast_verb(3, "Registered MGCP gateway '%s' at %s port %d\n", g->name, ast_inet_ntoa(g->addr.sin_addr), ntohs(g->addr.sin_port));
}
/* not dynamic, check if the name matches */
@@ -1934,6 +1945,7 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
format_t peercapability;
int peerNonCodecCapability;
struct sockaddr_in sin;
+ struct ast_sockaddr sin_tmp;
char *codecs;
struct ast_hostent ahp; struct hostent *hp;
int codec, codec_count=0;
@@ -1965,7 +1977,8 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
sin.sin_family = AF_INET;
memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
sin.sin_port = htons(portno);
- ast_rtp_instance_set_remote_address(sub->rtp, &sin);
+ ast_sockaddr_from_sin(&sin_tmp, &sin);
+ ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
ast_debug(3, "Peer RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
/* Scan through the RTP payload types specified in a "m=" line: */
ast_rtp_codecs_payloads_clear(ast_rtp_instance_get_codecs(sub->rtp), sub->rtp);
@@ -2148,6 +2161,7 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
int codec;
char costr[80];
struct sockaddr_in sin;
+ struct ast_sockaddr sin_tmp;
char v[256];
char s[256];
char o[256];
@@ -2157,6 +2171,7 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
char a[1024] = "";
format_t x;
struct sockaddr_in dest = { 0, };
+ struct ast_sockaddr dest_tmp;
struct mgcp_endpoint *p = sub->parent;
/* XXX We break with the "recommendation" and send our IP, in order that our
peer doesn't have to ast_gethostbyname() us XXX */
@@ -2165,9 +2180,11 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
return -1;
}
- ast_rtp_instance_get_local_address(sub->rtp, &sin);
+ ast_rtp_instance_get_local_address(sub->rtp, &sin_tmp);
+ ast_sockaddr_to_sin(&sin_tmp, &sin);
if (rtp) {
- ast_rtp_instance_get_remote_address(sub->rtp, &dest);
+ ast_rtp_instance_get_remote_address(sub->rtp, &dest_tmp);
+ ast_sockaddr_to_sin(&dest_tmp, &dest);
} else {
if (sub->tmpdest.sin_addr.s_addr) {
dest.sin_addr = sub->tmpdest.sin_addr;
@@ -2240,11 +2257,13 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_
char tmp[80];
struct mgcp_endpoint *p = sub->parent;
format_t x;
+ struct ast_sockaddr sub_tmpdest_tmp;
if (ast_strlen_zero(sub->cxident) && rtp) {
/* We don't have a CXident yet, store the destination and
wait a bit */
- ast_rtp_instance_get_remote_address(rtp, &sub->tmpdest);
+ ast_rtp_instance_get_remote_address(rtp, &sub_tmpdest_tmp);
+ ast_sockaddr_to_sin(&sub_tmpdest_tmp, &sub->tmpdest);
return 0;
}
ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
@@ -2876,6 +2895,8 @@ static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub
static void start_rtp(struct mgcp_subchannel *sub)
{
+ struct ast_sockaddr bindaddr_tmp;
+
ast_mutex_lock(&sub->lock);
/* check again to be on the safe side */
if (sub->rtp) {
@@ -2883,7 +2904,8 @@ static void start_rtp(struct mgcp_subchannel *sub)
sub->rtp = NULL;
}
/* Allocate the RTP now */
- sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr, NULL);
+ ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
+ sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
if (sub->rtp && sub->owner)
ast_channel_set_fd(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
if (sub->rtp) {
@@ -3967,22 +3989,32 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
/* Non-dynamic. Make sure we become that way if we're not */
AST_SCHED_DEL(sched, gw->expire);
gw->dynamic = 0;
- if (ast_get_ip(&gw->addr, v->value)) {
- if (!gw_reload) {
- ast_mutex_destroy(&gw->msgs_lock);
- ast_free(gw);
+ {
+ struct ast_sockaddr tmp;
+
+ ast_sockaddr_from_sin(&tmp, &gw->addr);
+ if (ast_get_ip(&tmp, v->value)) {
+ if (!gw_reload) {
+ ast_mutex_destroy(&gw->msgs_lock);
+ ast_free(gw);
+ }
+ return NULL;
}
- return NULL;
+ ast_sockaddr_to_sin(&tmp, &gw->addr);
}
}
} else if (!strcasecmp(v->name, "defaultip")) {
- if (ast_get_ip(&gw->defaddr, v->value)) {
+ struct ast_sockaddr tmp;
+
+ ast_sockaddr_from_sin(&tmp, &gw->defaddr);
+ if (ast_get_ip(&tmp, v->value)) {
if (!gw_reload) {
ast_mutex_destroy(&gw->msgs_lock);
ast_free(gw);
}
return NULL;
}
+ ast_sockaddr_to_sin(&tmp, &gw->defaddr);
} else if (!strcasecmp(v->name, "permit") ||
!strcasecmp(v->name, "deny")) {
gw->ha = ast_append_ha(v->name, v->value, gw->ha, NULL);
@@ -4325,8 +4357,19 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
if (gw->addr.sin_addr.s_addr && !ntohs(gw->addr.sin_port)) {
gw->addr.sin_port = htons(DEFAULT_MGCP_GW_PORT);
}
- if (gw->addr.sin_addr.s_addr && ast_ouraddrfor(&gw->addr.sin_addr, &gw->ourip)) {
- memcpy(&gw->ourip, &__ourip, sizeof(gw->ourip));
+ {
+ struct ast_sockaddr tmp1, tmp2;
+ struct sockaddr_in tmp3 = {0,};
+
+ tmp3.sin_addr = gw->ourip;
+ ast_sockaddr_from_sin(&tmp1, &gw->addr);
+ ast_sockaddr_from_sin(&tmp2, &tmp3);
+ if (gw->addr.sin_addr.s_addr && ast_ouraddrfor(&tmp1, &tmp2)) {
+ memcpy(&gw->ourip, &__ourip, sizeof(gw->ourip));
+ } else {
+ ast_sockaddr_to_sin(&tmp2, &tmp3);
+ gw->ourip = tmp3.sin_addr;
+ }
}
}
diff --git a/channels/chan_multicast_rtp.c b/channels/chan_multicast_rtp.c
index 24c073215..f385d4467 100644
--- a/channels/chan_multicast_rtp.c
+++ b/channels/chan_multicast_rtp.c
@@ -111,7 +111,8 @@ static struct ast_channel *multicast_rtp_request(const char *type, format_t form
{
char *tmp = ast_strdupa(data), *multicast_type = tmp, *destination, *control;
struct ast_rtp_instance *instance;
- struct sockaddr_in control_address = { .sin_family = AF_INET, }, destination_address = { .sin_family = AF_INET, };
+ struct ast_sockaddr control_address;
+ struct ast_sockaddr destination_address;
struct ast_channel *chan;
format_t fmt = ast_best_codec(format);
@@ -125,13 +126,15 @@ static struct ast_channel *multicast_rtp_request(const char *type, format_t form
}
*destination++ = '\0';
- if (ast_parse_arg(destination, PARSE_INADDR | PARSE_PORT_REQUIRE, &destination_address)) {
+ if (!ast_sockaddr_parse(&destination_address, destination,
+ PARSE_PORT_REQUIRE)) {
goto failure;
}
if ((control = strchr(destination, '/'))) {
*control++ = '\0';
- if (ast_parse_arg(control, PARSE_INADDR | PARSE_PORT_REQUIRE, &control_address)) {
+ if (!ast_sockaddr_parse(&control_address, control,
+ PARSE_PORT_REQUIRE)) {
goto failure;
}
}
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index c65d85b9f..d0c131f13 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -252,7 +252,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/monitor.h"
-#include "asterisk/netsock.h"
+#include "asterisk/netsock2.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/threadstorage.h"
@@ -1117,7 +1117,7 @@ static struct sip_auth *authl = NULL;
*/
static int sipsock = -1;
-struct sockaddr_in bindaddr; /*!< UDP: The address we bind to */
+struct ast_sockaddr bindaddr; /*!< UDP: The address we bind to */
/*! \brief our (internal) default address/port to put in SIP/SDP messages
* internip is initialized picking a suitable address from one of the
@@ -1125,7 +1125,7 @@ struct sockaddr_in bindaddr; /*!< UDP: The address we bind to */
* default address/port in SIP messages, and as the default address
* (but not port) in SDP messages.
*/
-static struct sockaddr_in internip;
+static struct ast_sockaddr internip;
/*! \brief our external IP address/port for SIP sessions.
* externip.sin_addr is only set when we know we might be behind
@@ -1145,8 +1145,8 @@ static struct sockaddr_in internip;
* Other variables (externhost, externexpire, externrefresh) are used
* to support the above functions.
*/
-static struct sockaddr_in externip; /*!< External IP address if we are behind NAT */
-static struct sockaddr_in media_address; /*!< External RTP IP address if we are behind NAT */
+static struct ast_sockaddr externip; /*!< External IP address if we are behind NAT */
+static struct ast_sockaddr media_address; /*!< External RTP IP address if we are behind NAT */
static char externhost[MAXHOSTNAMELEN]; /*!< External host name */
static time_t externexpire; /*!< Expiration counter for re-resolving external host name in dynamic DNS */
@@ -1165,7 +1165,7 @@ static struct ast_ha *localaddr; /*!< List of local networks, on the same sid
static int ourport_tcp; /*!< The port used for TCP connections */
static int ourport_tls; /*!< The port used for TCP/TLS connections */
-static struct sockaddr_in debugaddr;
+static struct ast_sockaddr debugaddr;
static struct ast_config *notify_types = NULL; /*!< The list of manual NOTIFY types we know how to send */
@@ -1201,9 +1201,10 @@ static int sip_setoption(struct ast_channel *chan, int option, void *data, int d
static int sip_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
static const char *sip_get_callid(struct ast_channel *chan);
-static int handle_request_do(struct sip_request *req, struct sockaddr_in *sin);
+static int handle_request_do(struct sip_request *req, struct ast_sockaddr *addr);
static int sip_standard_port(enum sip_transport type, int port);
static int sip_prepare_socket(struct sip_pvt *p);
+static int get_address_family_filter(const struct ast_sockaddr *addr);
/*--- Transmitting responses and requests */
static int sipsock_read(int *id, int fd, short events, void *ignore);
@@ -1212,7 +1213,7 @@ static int __sip_reliable_xmit(struct sip_pvt *p, int seqno, int resp, struct as
static void add_cc_call_info_to_response(struct sip_pvt *p, struct sip_request *resp);
static int __transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
static int retrans_pkt(const void *data);
-static int transmit_response_using_temp(ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg);
+static int transmit_response_using_temp(ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg);
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req);
static int transmit_response_reliable(struct sip_pvt *p, const char *msg, const struct sip_request *req);
static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const struct sip_request *req);
@@ -1248,11 +1249,11 @@ static int __sip_autodestruct(const void *data);
static void *registry_unref(struct sip_registry *reg, char *tag);
static int update_call_counter(struct sip_pvt *fup, int event);
static int auto_congest(const void *arg);
-static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int intended_method);
+static struct sip_pvt *find_call(struct sip_request *req, struct ast_sockaddr *addr, const int intended_method);
static void free_old_route(struct sip_route *route);
static void list_route(struct sip_route *route);
static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards);
-static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr_in *sin,
+static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sockaddr *addr,
struct sip_request *req, const char *uri);
static struct sip_pvt *get_sip_pvt_byid_locked(const char *callid, const char *totag, const char *fromtag);
static void check_pendings(struct sip_pvt *p);
@@ -1268,7 +1269,7 @@ static char get_sdp_line(int *start, int stop, struct sip_request *req, const ch
static int find_sdp(struct sip_request *req);
static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action);
static int process_sdp_o(const char *o, struct sip_pvt *p);
-static int process_sdp_c(const char *c, struct ast_hostent *hp);
+static int process_sdp_c(const char *c, struct ast_sockaddr *addr);
static int process_sdp_a_sendonly(const char *a, int *sendonly);
static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newaudiortp, int *last_rtpmap_codec);
static int process_sdp_a_video(const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newvideortp, int *last_rtpmap_codec);
@@ -1292,8 +1293,8 @@ static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *
const char *uri, enum xmittype reliable, int ignore);
static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_request *req,
int sipmethod, const char *uri, enum xmittype reliable,
- struct sockaddr_in *sin, struct sip_peer **authpeer);
-static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct sockaddr_in *sin);
+ struct ast_sockaddr *addr, struct sip_peer **authpeer);
+static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr);
/*--- Domain handling */
static int check_sip_domain(const char *domain, char *context, size_t len); /* Check if domain is one of our local domains */
@@ -1375,13 +1376,17 @@ static int sip_dtmfmode(struct ast_channel *chan, const char *data);
static int sip_addheader(struct ast_channel *chan, const char *data);
static int sip_do_reload(enum channelreloadreason reason);
static char *sip_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
+static int ast_sockaddr_resolve_first_af(struct ast_sockaddr *addr,
+ const char *name, int flag, int family);
+static int ast_sockaddr_resolve_first(struct ast_sockaddr *addr,
+ const char *name, int flag);
/*--- Debugging
Functions for enabling debug per IP or fully, or enabling history logging for
a SIP dialog
*/
static void sip_dump_history(struct sip_pvt *dialog); /* Dump history to debuglog at end of dialog, before destroying data */
-static inline int sip_debug_test_addr(const struct sockaddr_in *addr);
+static inline int sip_debug_test_addr(const struct ast_sockaddr *addr);
static inline int sip_debug_test_pvt(struct sip_pvt *p);
static void append_history_full(struct sip_pvt *p, const char *fmt, ...);
static void sip_dump_history(struct sip_pvt *dialog);
@@ -1394,7 +1399,7 @@ static void sip_destroy_peer_fn(void *peer);
static void set_peer_defaults(struct sip_peer *peer);
static struct sip_peer *temp_peer(const char *name);
static void register_peer_exten(struct sip_peer *peer, int onoff);
-static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int forcenamematch, int devstate_only, int transport);
+static struct sip_peer *find_peer(const char *peer, struct ast_sockaddr *addr, int realtime, int forcenamematch, int devstate_only, int transport);
static int sip_poke_peer_s(const void *data);
static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req);
static void reg_source_db(struct sip_peer *peer);
@@ -1404,15 +1409,15 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask
static void set_socket_transport(struct sip_socket *socket, int transport);
/* Realtime device support */
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms);
+static void realtime_update_peer(const char *peername, struct ast_sockaddr *addr, const char *username, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms);
static void update_peer(struct sip_peer *p, int expire);
static struct ast_variable *get_insecure_variable_from_config(struct ast_config *config);
static const char *get_name_from_variable(struct ast_variable *var, const char *newpeername);
-static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin, int devstate_only);
+static struct sip_peer *realtime_peer(const char *peername, struct ast_sockaddr *sin, int devstate_only);
static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
/*--- Internal UA client handling (outbound registrations) */
-static void ast_sip_ouraddrfor(struct in_addr *them, struct sockaddr_in *us, struct sip_pvt *p);
+static void ast_sip_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us, struct sip_pvt *p);
static void sip_registry_destroy(struct sip_registry *reg);
static int sip_register(const char *value, int lineno);
static const char *regstate2str(enum sipregistrystate regstate) attribute_const;
@@ -1469,13 +1474,13 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
static int init_resp(struct sip_request *resp, const char *msg);
static inline int resp_needs_contact(const char *msg, enum sipmethod method);
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req);
-static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p);
+static const struct ast_sockaddr *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 sockaddr_in *sin, int newdialog, struct sockaddr_in *remote_address);
+static int create_addr(struct sip_pvt *dialog, const char *opeer, struct ast_sockaddr *addr, int newdialog, struct ast_sockaddr *remote_address);
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);
+static void build_callid_registry(struct sip_registry *reg, const struct ast_sockaddr *ourip, const char *fromdomain);
static void make_our_tag(char *tagbuf, size_t len);
static int add_header(struct sip_request *req, const char *var, const char *value);
static int add_content(struct sip_request *req, const char *line);
@@ -1493,19 +1498,19 @@ static void append_date(struct sip_request *req);
static void build_contact(struct sip_pvt *p);
/*------Request handling functions */
-static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock);
+static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int *recount, int *nounlock);
static int handle_request_update(struct sip_pvt *p, struct sip_request *req);
-static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, const char *e, int *nounlock);
+static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct ast_sockaddr *addr, int *recount, const char *e, int *nounlock);
static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, int *nounlock);
static int handle_request_bye(struct sip_pvt *p, struct sip_request *req);
-static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, const char *e);
+static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *sin, const char *e);
static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req);
static int handle_request_message(struct sip_pvt *p, struct sip_request *req);
-static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, const char *e);
+static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int seqno, const char *e);
static void handle_request_info(struct sip_pvt *p, struct sip_request *req);
static int handle_request_options(struct sip_pvt *p, struct sip_request *req);
-static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *nounlock);
-static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, const char *e);
+static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct ast_sockaddr *addr, int *nounlock);
+static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int seqno, const char *e);
static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno, int *nounlock);
/*------Response handling functions */
@@ -1877,7 +1882,7 @@ static int sip_cc_monitor_request_cc(struct ast_cc_monitor *monitor, int *availa
sip_pvt_lock(monitor_instance->subscription_pvt);
create_addr(monitor_instance->subscription_pvt, monitor_instance->peername, 0, 1, NULL);
- ast_sip_ouraddrfor(&monitor_instance->subscription_pvt->sa.sin_addr, &monitor_instance->subscription_pvt->ourip, monitor_instance->subscription_pvt);
+ ast_sip_ouraddrfor(&monitor_instance->subscription_pvt->sa, &monitor_instance->subscription_pvt->ourip, monitor_instance->subscription_pvt);
monitor_instance->subscription_pvt->subscribed = CALL_COMPLETION;
monitor_instance->subscription_pvt->expiry = when;
@@ -2793,14 +2798,19 @@ static int proxy_update(struct sip_proxy *proxy)
{
/* if it's actually an IP address and not a name,
there's no need for a managed lookup */
- if (!inet_aton(proxy->name, &proxy->ip.sin_addr)) {
+ if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) {
/* Ok, not an IP address, then let's check if it's a domain or host */
/* XXX Todo - if we have proxy port, don't do SRV */
+ proxy->ip.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) {
- ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
- return FALSE;
+ ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
+ return FALSE;
}
+
}
+
+ ast_sockaddr_set_port(&proxy->ip, proxy->port);
+
proxy->last_dnsupdate = time(NULL);
return TRUE;
}
@@ -2819,26 +2829,6 @@ unsigned int port_str2int(const char *pt, unsigned int standard)
return port;
}
-/*! \brief Allocate and initialize sip proxy */
-static struct sip_proxy *proxy_allocate(char *name, char *port, int force)
-{
- struct sip_proxy *proxy;
-
- if (ast_strlen_zero(name)) {
- return NULL;
- }
-
- proxy = ao2_alloc(sizeof(*proxy), NULL);
- if (!proxy)
- return NULL;
- proxy->force = force;
- ast_copy_string(proxy->name, name, sizeof(proxy->name));
- proxy->ip.sin_port = htons(port_str2int(port, STANDARD_SIP_PORT));
- proxy->ip.sin_family = AF_INET;
- proxy_update(proxy);
- return proxy;
-}
-
/*! \brief Get default outbound proxy or global proxy */
static struct sip_proxy *obproxy_get(struct sip_pvt *dialog, struct sip_peer *peer)
{
@@ -2889,21 +2879,13 @@ static int find_sip_method(const char *msg)
}
/*! \brief See if we pass debug IP filter */
-static inline int sip_debug_test_addr(const struct sockaddr_in *addr)
+static inline int sip_debug_test_addr(const struct ast_sockaddr *addr)
{
- if (!sipdebug)
- return 0;
- if (debugaddr.sin_addr.s_addr) {
- if (((ntohs(debugaddr.sin_port) != 0)
- && (debugaddr.sin_port != addr->sin_port))
- || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
- return 0;
- }
- return 1;
+ return sipdebug && !ast_sockaddr_isnull(addr) && !ast_sockaddr_cmp_addr(&debugaddr, addr);
}
/*! \brief The real destination address for a write */
-static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p)
+static const struct ast_sockaddr *sip_real_dst(const struct sip_pvt *p)
{
if (p->outboundproxy)
return &p->outboundproxy->ip;
@@ -3007,15 +2989,15 @@ static inline const char *get_transport_pvt(struct sip_pvt *p)
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);
+ const struct ast_sockaddr *dst = sip_real_dst(p);
- ast_debug(2, "Trying to put '%.11s' onto %s socket destined for %s:%d\n", data->str, get_transport_pvt(p), ast_inet_ntoa(dst->sin_addr), htons(dst->sin_port));
+ ast_debug(2, "Trying to put '%.11s' onto %s socket destined for %s\n", data->str, get_transport_pvt(p), ast_sockaddr_stringify(dst));
if (sip_prepare_socket(p) < 0)
return XMIT_ERROR;
if (p->socket.type == SIP_TRANSPORT_UDP) {
- res = sendto(p->socket.fd, data->str, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
+ res = ast_sendto(p->socket.fd, data->str, len, 0, dst);
} else if (p->socket.tcptls_session) {
res = sip_tcptls_write(p->socket.tcptls_session, data->str, len);
} else {
@@ -3034,7 +3016,7 @@ static int __sip_xmit(struct sip_pvt *p, struct ast_str *data, int len)
}
}
if (res != len)
- ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno));
+ ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s returned %d: %s\n", data, len, ast_sockaddr_stringify(dst), res, strerror(errno));
return res;
}
@@ -3046,10 +3028,10 @@ static void build_via(struct sip_pvt *p)
const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : "";
/* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
- snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s:%d;branch=z9hG4bK%08x%s",
+ snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s",
get_transport_pvt(p),
- ast_inet_ntoa(p->ourip.sin_addr),
- ntohs(p->ourip.sin_port), (int) p->branch, rport);
+ ast_sockaddr_stringify(&p->ourip),
+ (int) p->branch, rport);
}
/*! \brief NAT fix - decide which IP address to use for Asterisk server?
@@ -3059,9 +3041,11 @@ static void build_via(struct sip_pvt *p)
* externip or can get away with our internal bindaddr
* 'us' is always overwritten.
*/
-static void ast_sip_ouraddrfor(struct in_addr *them, struct sockaddr_in *us, struct sip_pvt *p)
+static void ast_sip_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us, struct sip_pvt *p)
{
- struct sockaddr_in theirs;
+ struct ast_sockaddr theirs;
+ struct sockaddr_in theirs_sin, externip_sin, us_sin;
+
/* Set want_remap to non-zero if we want to remap 'us' to an externally
* reachable IP address and port. This is done if:
* 1. we have a localaddr list (containing 'internal' addresses marked
@@ -3074,76 +3058,100 @@ static void ast_sip_ouraddrfor(struct in_addr *them, struct sockaddr_in *us, str
* when passed to ast_apply_ha() so it does need to be remapped.
* This fourth condition is checked later.
*/
- int want_remap;
+ int want_remap = 0;
- *us = internip; /* starting guess for the internal address */
+ ast_sockaddr_copy(us, &internip); /* starting guess for the internal address */
/* now ask the system what would it use to talk to 'them' */
- ast_ouraddrfor(them, &us->sin_addr);
- theirs.sin_addr = *them;
+ ast_ouraddrfor(them, us);
+ ast_sockaddr_copy(&theirs, them);
- want_remap = localaddr &&
- (externip.sin_addr.s_addr || stunaddr.sin_addr.s_addr) &&
- ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ;
+ if (ast_sockaddr_is_ipv6(&theirs)) {
+ if (localaddr && !ast_sockaddr_isnull(&externip)) {
+ ast_log(LOG_WARNING, "Address remapping activated in sip.conf "
+ "but we're using IPv6, which doesn't need it. Please "
+ "remove \"localnet\" and/or \"externip\" settings.\n");
+ }
+ } else {
+ ast_sockaddr_to_sin(&theirs, &theirs_sin);
+ ast_sockaddr_to_sin(us, &us_sin);
+
+ want_remap = localaddr &&
+ !(ast_sockaddr_isnull(&externip) && stunaddr.sin_addr.s_addr) &&
+ ast_apply_ha(localaddr, &theirs_sin) == AST_SENSE_ALLOW ;
+ }
if (want_remap &&
- (!sip_cfg.matchexterniplocally || !ast_apply_ha(localaddr, us)) ) {
+ (!sip_cfg.matchexterniplocally || !ast_apply_ha(localaddr, &us_sin)) ) {
/* if we used externhost or stun, see if it is time to refresh the info */
if (externexpire && time(NULL) >= externexpire) {
if (stunaddr.sin_addr.s_addr) {
- ast_stun_request(sipsock, &stunaddr, NULL, &externip);
+ ast_sockaddr_to_sin(&externip, &externip_sin);
+ ast_stun_request(sipsock, &stunaddr, NULL, &externip_sin);
} else {
- if (ast_parse_arg(externhost, PARSE_INADDR, &externip))
+ if (ast_sockaddr_resolve_first(&externip, externhost, 0)) {
ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
+ }
+ externexpire = time(NULL);
}
externexpire = time(NULL) + externrefresh;
}
- if (externip.sin_addr.s_addr) {
- *us = externip;
+ if (ast_sockaddr_isnull(&externip)) {
+ ast_sockaddr_copy(us, &externip);
switch (p->socket.type) {
case SIP_TRANSPORT_TCP:
- us->sin_port = htons(externtcpport);
+ if (!externtcpport && ast_sockaddr_port(&externip)) {
+ /* for consistency, default to the externip port */
+ externtcpport = ast_sockaddr_port(&externip);
+ }
+ ast_sockaddr_set_port(us, externtcpport);
break;
case SIP_TRANSPORT_TLS:
- us->sin_port = htons(externtlsport);
+ ast_sockaddr_set_port(us, externtlsport);
break;
case SIP_TRANSPORT_UDP:
break; /* fall through */
default:
- us->sin_port = htons(STANDARD_SIP_PORT); /* we should never get here */
+ /* we should never get here */
+ ast_sockaddr_set_port(us, STANDARD_SIP_PORT);
}
}
- else
+ else {
ast_log(LOG_WARNING, "stun failed\n");
+ }
ast_debug(1, "Target address %s is not local, substituting externip\n",
- ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
+ ast_sockaddr_stringify(them));
} else if (p) {
/* no remapping, but we bind to a specific address, so use it. */
switch (p->socket.type) {
case SIP_TRANSPORT_TCP:
- if (sip_tcp_desc.local_address.sin_addr.s_addr) {
- *us = sip_tcp_desc.local_address;
+ if (!ast_sockaddr_is_any(&sip_tcp_desc.local_address)) {
+ ast_sockaddr_copy(us,
+ &sip_tcp_desc.local_address);
} else {
- us->sin_port = sip_tcp_desc.local_address.sin_port;
+ ast_sockaddr_set_port(us,
+ ast_sockaddr_port(&sip_tcp_desc.local_address));
}
break;
case SIP_TRANSPORT_TLS:
- if (sip_tls_desc.local_address.sin_addr.s_addr) {
- *us = sip_tls_desc.local_address;
+ if (!ast_sockaddr_is_any(&sip_tls_desc.local_address)) {
+ ast_sockaddr_copy(us,
+ &sip_tls_desc.local_address);
} else {
- us->sin_port = sip_tls_desc.local_address.sin_port;
+ ast_sockaddr_set_port(us,
+ ast_sockaddr_port(&sip_tls_desc.local_address));
}
- break;
+ break;
case SIP_TRANSPORT_UDP:
/* fall through on purpose */
default:
- if (bindaddr.sin_addr.s_addr) {
- *us = bindaddr;
+ if (!ast_sockaddr_is_any(&bindaddr)) {
+ ast_sockaddr_copy(us, &bindaddr);
}
}
- } else if (bindaddr.sin_addr.s_addr) {
- *us = bindaddr;
+ } else if (!ast_sockaddr_is_any(&bindaddr)) {
+ ast_sockaddr_copy(us, &bindaddr);
}
- ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s:%d\n", get_transport(p->socket.type), ast_inet_ntoa(us->sin_addr), ntohs(us->sin_port));
+ ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s\n", get_transport(p->socket.type), ast_sockaddr_stringify(us));
}
/*! \brief Append to SIP dialog history with arg list */
@@ -3231,11 +3239,11 @@ static int retrans_pkt(const void *data)
}
if (sip_debug_test_pvt(pkt->owner)) {
- const struct sockaddr_in *dst = sip_real_dst(pkt->owner);
- ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n",
+ const struct ast_sockaddr *dst = sip_real_dst(pkt->owner);
+ ast_verbose("Retransmitting #%d (%s) to %s:\n%s\n---\n",
pkt->retrans, sip_nat_mode(pkt->owner),
- ast_inet_ntoa(dst->sin_addr),
- ntohs(dst->sin_port), pkt->data->str);
+ ast_sockaddr_stringify(dst),
+ pkt->data->str);
}
append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data->str);
@@ -3709,12 +3717,12 @@ static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmitty
finalize_content(req);
add_blank(req);
if (sip_debug_test_pvt(p)) {
- const struct sockaddr_in *dst = sip_real_dst(p);
+ const struct ast_sockaddr *dst = sip_real_dst(p);
- ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n",
+ ast_verbose("\n<--- %sTransmitting (%s) to %s --->\n%s\n<------------>\n",
reliable ? "Reliably " : "", sip_nat_mode(p),
- ast_inet_ntoa(dst->sin_addr),
- ntohs(dst->sin_port), req->data->str);
+ ast_sockaddr_stringify(dst),
+ req->data->str);
}
if (p->do_history) {
struct sip_request tmp = { .rlPart1 = 0, };
@@ -3755,10 +3763,11 @@ static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittyp
finalize_content(req);
add_blank(req);
if (sip_debug_test_pvt(p)) {
- if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT))
- 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->str);
- else
- ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port), req->data->str);
+ if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) {
+ ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->recv), req->data->str);
+ } else {
+ ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->sa), req->data->str);
+ }
}
if (p->do_history) {
struct sip_request tmp = { .rlPart1 = 0, };
@@ -4012,7 +4021,7 @@ static int sip_sendtext(struct ast_channel *ast, const char *text)
that name and store that in the "regserver" field in the sippeers
table to facilitate multi-server setups.
*/
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms)
+static void realtime_update_peer(const char *peername, struct ast_sockaddr *addr, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms)
{
char port[10];
char ipaddr[INET_ADDRSTRLEN];
@@ -4033,9 +4042,9 @@ static void realtime_update_peer(const char *peername, struct sockaddr_in *sin,
snprintf(str_lastms, sizeof(str_lastms), "%d", lastms);
snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */
- ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
- snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
-
+ ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr));
+ ast_copy_string(port, ast_sockaddr_stringify_port(addr), sizeof(port));
+
if (ast_strlen_zero(sysname)) /* No system name, disable this */
sysname = NULL;
else if (sip_cfg.rtsave_sysname)
@@ -4209,7 +4218,7 @@ static const char *get_name_from_variable(struct ast_variable *var, const char *
* This returns a pointer to a peer and because we use build_peer, we can rest
* assured that the refcount is bumped.
*/
-static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_in *sin, int devstate_only)
+static struct sip_peer *realtime_peer(const char *newpeername, struct ast_sockaddr *addr, int devstate_only)
{
struct sip_peer *peer;
struct ast_variable *var = NULL;
@@ -4219,7 +4228,6 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
char ipaddr[INET_ADDRSTRLEN];
char portstring[6]; /*up to 5 digits plus null terminator*/
char *cat = NULL;
- unsigned short portnum;
int realtimeregs = ast_check_realtime("sipregs");
/* First check on peer name */
@@ -4228,8 +4236,9 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", SENTINEL);
- if (!var && sin)
- var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
+ if (!var && addr) {
+ var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_sockaddr_stringify_addr(addr), SENTINEL);
+ }
if (!var) {
var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL);
/*!\note
@@ -4238,16 +4247,21 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
* is because we only have the IP address and the host field might be
* set as a name (and the reverse PTR might not match).
*/
- if (var && sin) {
+ if (var && addr) {
for (tmp = var; tmp; tmp = tmp->next) {
if (!strcasecmp(tmp->name, "host")) {
- struct hostent *hp;
- struct ast_hostent ahp;
- if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
+ struct ast_sockaddr *addrs = NULL;
+
+ if (ast_sockaddr_resolve(&addrs,
+ tmp->value,
+ PARSE_PORT_FORBID,
+ get_address_family_filter(&bindaddr)) <= 0 ||
+ ast_sockaddr_cmp(&addrs[0], addr)) {
/* No match */
ast_variables_destroy(var);
var = NULL;
}
+ ast_free(addrs);
break;
}
}
@@ -4255,10 +4269,9 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
}
}
- if (!var && sin) { /* Then check on IP address for dynamic peers */
- ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
- portnum = ntohs(sin->sin_port);
- sprintf(portstring, "%u", portnum);
+ if (!var && addr) { /* Then check on IP address for dynamic peers */
+ ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr));
+ ast_copy_string(portstring, ast_sockaddr_stringify_port(addr), sizeof(portstring));
var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL); /* First check for fixed IP hosts */
if (var) {
if (realtimeregs) {
@@ -4368,7 +4381,7 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
ref_peer(peer, "add registration ref"));
}
ao2_t_link(peers, peer, "link peer into peers table");
- if (peer->addr.sin_addr.s_addr) {
+ if (!ast_sockaddr_isnull(&peer->addr)) {
ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
}
}
@@ -4425,7 +4438,7 @@ static int find_by_name(void *obj, void *arg, void *data, int flags)
* \note Avoid using this function in new functions if there is a way to avoid it,
* since it might cause a database lookup.
*/
-static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int which_objects, int devstate_only, int transport)
+static struct sip_peer *find_peer(const char *peer, struct ast_sockaddr *addr, int realtime, int which_objects, int devstate_only, int transport)
{
struct sip_peer *p = NULL;
struct sip_peer tmp_peer;
@@ -4433,9 +4446,8 @@ static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int
if (peer) {
ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table");
- } else if (sin) { /* search by addr? */
- tmp_peer.addr.sin_addr.s_addr = sin->sin_addr.s_addr;
- tmp_peer.addr.sin_port = sin->sin_port;
+ } else if (addr) { /* search by addr? */
+ ast_sockaddr_copy(&tmp_peer.addr, addr);
tmp_peer.flags[0].flags = 0;
tmp_peer.transports = transport;
p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table"); /* WAS: p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */
@@ -4449,7 +4461,7 @@ static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int
}
if (!p && (realtime || devstate_only)) {
- p = realtime_peer(peer, sin, devstate_only);
+ p = realtime_peer(peer, addr, devstate_only);
if (p) {
switch (which_objects) {
case FINDUSERS:
@@ -4582,17 +4594,20 @@ static void copy_socket_data(struct sip_socket *to_sock, const struct sip_socket
*/
static int dialog_initialize_rtp(struct sip_pvt *dialog)
{
+ struct ast_sockaddr bindaddr_tmp;
+
if (!sip_methods[dialog->method].need_rtp) {
return 0;
}
- if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr, NULL))) {
+ ast_sockaddr_copy(&bindaddr_tmp, &bindaddr);
+ if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
return -1;
}
if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) ||
(ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (dialog->capability & AST_FORMAT_VIDEO_MASK))) {
- if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr, NULL))) {
+ if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
return -1;
}
ast_rtp_instance_set_timeout(dialog->vrtp, global_rtptimeout);
@@ -4602,7 +4617,7 @@ static int dialog_initialize_rtp(struct sip_pvt *dialog)
}
if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT)) {
- if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr, NULL))) {
+ if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
return -1;
}
ast_rtp_instance_set_timeout(dialog->trtp, global_rtptimeout);
@@ -4634,7 +4649,6 @@ static int dialog_initialize_rtp(struct sip_pvt *dialog)
*/
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 */
@@ -4642,9 +4656,9 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
return -1;
copy_socket_data(&dialog->socket, &peer->socket);
- if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
+ if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) &&
(!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) {
- dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr;
+ dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr;
dialog->recv = dialog->sa;
} else
return -1;
@@ -4656,8 +4670,11 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
dialog->capability = peer->capability;
dialog->prefs = peer->prefs;
if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
+ struct sockaddr_in bindaddr_tmp;
+
/* t38pt_udptl was enabled in the peer and not in [general] */
- if (dialog->udptl || (!dialog->udptl && (dialog->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr)))) {
+ ast_sockaddr_to_sin(&bindaddr, &bindaddr_tmp);
+ if (dialog->udptl || (!dialog->udptl && (dialog->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr_tmp.sin_addr)))) {
dialog->t38_maxdatagram = peer->t38_maxdatagram;
set_t38_capabilities(dialog);
} else {
@@ -4723,7 +4740,7 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
dialog->disallowed_methods = peer->disallowed_methods;
ast_cc_copy_config_params(dialog->cc_params, peer->cc_params);
if (ast_strlen_zero(dialog->tohost))
- ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
+ ast_string_field_set(dialog, tohost, ast_sockaddr_stringify_host(&dialog->sa));
if (!ast_strlen_zero(peer->fromdomain)) {
ast_string_field_set(dialog, fromdomain, peer->fromdomain);
if (!dialog->initreq.headers) {
@@ -4779,24 +4796,27 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
/*! \brief create address structure from device 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 sockaddr_in *sin, int newdialog, struct sockaddr_in *remote_address)
+static int create_addr(struct sip_pvt *dialog, const char *opeer, struct ast_sockaddr *addr, int newdialog, struct ast_sockaddr *remote_address)
{
- struct hostent *hp;
- struct ast_hostent ahp;
struct sip_peer *peer;
- char *port;
- int portno = 0;
- char host[MAXHOSTNAMELEN], *hostn;
- char peername[256];
+ char *peername, *peername2, *hostn;
+ char host[MAXHOSTNAMELEN];
+ char service[MAXHOSTNAMELEN];
int srv_ret = 0;
+ int tportno;
- ast_copy_string(peername, opeer, sizeof(peername));
- port = strchr(peername, ':');
- if (port) {
- *port++ = '\0';
+ AST_DECLARE_APP_ARGS(hostport,
+ AST_APP_ARG(host);
+ AST_APP_ARG(port);
+ );
+
+ peername = ast_strdupa(opeer);
+ peername2 = ast_strdupa(opeer);
+ AST_NONSTANDARD_RAW_ARGS(hostport, peername2, ':');
+
+ if (hostport.port)
dialog->portinuri = 1;
- }
- dialog->sa.sin_family = AF_INET;
+
dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
@@ -4807,12 +4827,8 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
set_socket_transport(&dialog->socket, 0);
}
res = create_addr_from_peer(dialog, peer);
- if (remote_address && remote_address->sin_addr.s_addr) {
- dialog->sa = dialog->recv = *remote_address;
- } else if (!ast_strlen_zero(port)) {
- if ((portno = atoi(port))) {
- dialog->sa.sin_port = dialog->recv.sin_port = htons(portno);
- }
+ if (!ast_sockaddr_isnull(remote_address)) {
+ ast_sockaddr_copy(&dialog->sa, remote_address);
}
dialog->relatedpeer = ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer");
unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup");
@@ -4823,20 +4839,15 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
return -1;
}
- ast_string_field_set(dialog, tohost, peername);
+ ast_string_field_set(dialog, tohost, hostport.host);
dialog->allowed_methods &= ~sip_cfg.disallowed_methods;
/* Get the outbound proxy information */
ref_proxy(dialog, obproxy_get(dialog, NULL));
- if (sin) {
+ if (addr) {
/* This address should be updated using dnsmgr */
- memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr));
- if (!sin->sin_port) {
- portno = port_str2int(port, (dialog->socket.type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT);
- } else {
- portno = ntohs(sin->sin_port);
- }
+ ast_sockaddr_copy(&dialog->sa, addr);
} else {
/* Let's see if we can find the host in DNS. First try DNS SRV records,
@@ -4848,33 +4859,35 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
/* Section 4.2 of RFC 3263 specifies that if a port number is specified, then
* an A record lookup should be used instead of SRV.
*/
- if (!port && sip_cfg.srvlookup) {
- char service[MAXHOSTNAMELEN];
- int tportno;
-
+ if (!hostport.port && sip_cfg.srvlookup) {
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) {
+ if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno,
+ service)) > 0) {
hostn = host;
- portno = tportno;
}
}
- if (!portno)
- portno = port_str2int(port, (dialog->socket.type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT);
- hp = ast_gethostbyname(hostn, &ahp);
- if (!hp) {
+
+ if (ast_sockaddr_resolve_first(&dialog->sa, hostn, 0)) {
ast_log(LOG_WARNING, "No such host: %s\n", peername);
- return -1;
}
- memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
+
+ if (srv_ret > 0) {
+ ast_sockaddr_set_port(&dialog->sa, tportno);
+ }
}
if (!dialog->socket.type)
set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP);
- if (!dialog->socket.port)
- dialog->socket.port = bindaddr.sin_port;
- dialog->sa.sin_port = htons(portno);
- dialog->recv = dialog->sa;
+ if (!dialog->socket.port) {
+ dialog->socket.port = htons(ast_sockaddr_port(&bindaddr));
+ }
+
+ if (!ast_sockaddr_port(&dialog->sa)) {
+ ast_sockaddr_set_port(&dialog->sa,
+ (dialog->socket.type == SIP_TRANSPORT_TLS) ?
+ STANDARD_TLS_PORT : STANDARD_SIP_PORT);
+ }
+ ast_sockaddr_copy(&dialog->recv, &dialog->sa);
return 0;
}
@@ -6800,16 +6813,12 @@ static char *generate_random_string(char *buf, size_t size)
static char *generate_uri(struct sip_pvt *pvt, char *buf, size_t size)
{
struct ast_str *uri = ast_str_alloca(size);
- int ourport = ntohs(pvt->ourip.sin_port);
ast_str_set(&uri, 0, "%s", pvt->socket.type == SIP_TRANSPORT_TLS ? "sips:" : "sip:");
/* Here would be a great place to generate a UUID, but for now we'll
* use the handy random string generation function we already have
*/
ast_str_append(&uri, 0, "%s", generate_random_string(buf, size));
- ast_str_append(&uri, 0, "@%s", ast_inet_ntoa(pvt->ourip.sin_addr));
- if (!sip_standard_port(pvt->socket.type, ourport)) {
- ast_str_append(&uri, 0, ":%d", ourport);
- }
+ ast_str_append(&uri, 0, "@%s", ast_sockaddr_stringify(&pvt->ourip));
ast_copy_string(buf, ast_str_buffer(uri), size);
return buf;
}
@@ -6819,18 +6828,18 @@ static void build_callid_pvt(struct sip_pvt *pvt)
{
char buf[33];
- const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip.sin_addr));
+ const char *host = S_OR(pvt->fromdomain, ast_sockaddr_stringify(&pvt->ourip));
ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
}
/*! \brief Build SIP Call-ID value for a REGISTER transaction */
-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, const struct ast_sockaddr *ourip, const char *fromdomain)
{
char buf[33];
- const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
+ const char *host = S_OR(fromdomain, ast_sockaddr_stringify_host(ourip));
ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
}
@@ -6865,7 +6874,7 @@ static struct sip_st_dlg* sip_st_alloc(struct sip_pvt *const p)
* Returns a reference to the object so whoever uses it later must
* remember to release the reference.
*/
-struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
+struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
int useglobal_nat, const int intended_method, struct sip_request *req)
{
struct sip_pvt *p;
@@ -6909,11 +6918,11 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
}
- if (!sin)
+ if (!addr) {
p->ourip = internip;
- else {
- p->sa = *sin;
- ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
+ } else {
+ ast_sockaddr_copy(&p->sa, addr);
+ ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
}
/* Copy global flags to this PVT at setup. */
@@ -6930,7 +6939,10 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
if (sip_methods[intended_method].need_rtp) {
if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
- if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr))) {
+ struct sockaddr_in bindaddr_tmp;
+
+ ast_sockaddr_to_sin(&bindaddr, &bindaddr_tmp);
+ if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr_tmp.sin_addr))) {
ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio);
p->t38_maxdatagram = global_t38_maxdatagram;
} else {
@@ -6943,10 +6955,11 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
p->autoframing = global_autoframing;
}
- if (useglobal_nat && sin) {
+ if (useglobal_nat && addr) {
/* Setup NAT structure according to global settings if we have an address */
ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT);
- p->recv = *sin;
+ ast_sockaddr_copy(&p->recv, addr);
+
do_setnat(p);
}
@@ -6990,7 +7003,7 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
* Returns a reference to the sip_pvt object, remember to give it back once done.
* Called by handle_incoming(), sipsock_read
*/
-static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
+static struct sip_pvt *find_call(struct sip_request *req, struct ast_sockaddr *addr, const int intended_method)
{
struct sip_pvt *p = NULL;
char *tag = ""; /* note, tag is never NULL */
@@ -7009,7 +7022,8 @@ static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *si
/* RFC 3261 section 24.4.1. Send a 400 Bad Request if the request is malformed. */
if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
- transmit_response_using_temp(callid, sin, 1, intended_method, req, "400 Bad Request");
+ transmit_response_using_temp(callid, addr, 1, intended_method,
+ req, "400 Bad Request");
}
return NULL; /* Invalid packet */
}
@@ -7096,10 +7110,10 @@ static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *si
if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
if (intended_method == SIP_REFER) {
/* We do support REFER, but not outside of a dialog yet */
- transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
+ transmit_response_using_temp(callid, addr, 1, intended_method, req, "603 Declined (no dialog)");
} else {
/* Ok, time to create a new SIP dialog object, a pvt */
- if ((p = sip_alloc(callid, sin, 1, intended_method, req))) {
+ if ((p = sip_alloc(callid, addr, 1, intended_method, req))) {
/* Ok, we've created a dialog, let's go and process it */
sip_pvt_lock(p);
} else {
@@ -7111,18 +7125,18 @@ static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *si
Sorry, we apologize for the inconvienience
*/
- transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
+ transmit_response_using_temp(callid, addr, 1, intended_method, req, "500 Server internal error");
ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
}
}
return p; /* can be NULL */
} else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
/* A method we do not support, let's take it on the volley */
- transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
+ transmit_response_using_temp(callid, addr, 1, intended_method, req, "501 Method Not Implemented");
ast_debug(2, "Got a request with unsupported SIP method.\n");
} else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
/* This is a request outside of a dialog that we don't know about */
- transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
+ transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist");
ast_debug(2, "That's odd... Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>");
}
/* We do not respond to responses for dialogs that we don't know about, we just drop
@@ -7572,7 +7586,7 @@ static int find_sdp(struct sip_request *req)
}
-static int get_ip_and_port_from_sdp(struct sip_request *req, const enum media_type media, struct sockaddr_in *sin)
+static int get_ip_and_port_from_sdp(struct sip_request *req, const enum media_type media, struct ast_sockaddr *addr)
{
const char *m;
const char *c;
@@ -7581,14 +7595,13 @@ static int get_ip_and_port_from_sdp(struct sip_request *req, const enum media_ty
int x = 0;
int numberofports;
int len;
- char host[258] = ""; /*Initialize to empty so we will know if we have any input */
- struct ast_hostent audiohp;
- struct hostent *hp;
+ int af;
+ char proto[4], host[258] = ""; /*Initialize to empty so we will know if we have any input */
c = get_sdp_iterate(&citerator, req, "c");
- if (sscanf(c, "IN IP4 %256s", host) != 1) {
- ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
- /* Continue since there may be a valid host in a c= line specific to the audio stream */
+ if (sscanf(c, "IN %3s %256s", proto, host) != 2) {
+ ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
+ /* Continue since there may be a valid host in a c= line specific to the audio stream */
}
/* We only want the m and c lines for audio */
for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) {
@@ -7602,25 +7615,31 @@ static int get_ip_and_port_from_sdp(struct sip_request *req, const enum media_ty
*/
c = get_sdp_iterate(&citerator, req, "c");
if (!ast_strlen_zero(c)) {
- sscanf(c, "IN IP4 %256s", host);
+ sscanf(c, "IN %3s %256s", proto, host);
}
break;
}
}
+ if (!strcmp("IP4", proto)) {
+ af = AF_INET;
+ } else if (!strcmp("IP6", proto)) {
+ af = AF_INET6;
+ } else {
+ ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto);
+ return -1;
+ }
+
if (ast_strlen_zero(host) || x == 0) {
ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video");
return -1;
}
- hp = ast_gethostbyname(host, &audiohp);
- if (!hp) {
+ if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) {
ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video");
return -1;
}
- memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
- sin->sin_port = htons(x);
return 0;
}
@@ -7644,23 +7663,20 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
int len = -1;
/* Host information */
- struct ast_hostent sessionhp;
- struct ast_hostent audiohp;
- struct ast_hostent videohp;
- struct ast_hostent texthp;
- struct ast_hostent imagehp;
- struct hostent *hp = NULL; /*!< RTP Audio host IP */
- struct hostent *vhp = NULL; /*!< RTP video host IP */
- struct hostent *thp = NULL; /*!< RTP text host IP */
- struct hostent *ihp = NULL; /*!< UDPTL host ip */
+ struct ast_sockaddr sessionsa;
+ struct ast_sockaddr audiosa;
+ struct ast_sockaddr videosa;
+ struct ast_sockaddr textsa;
+ struct ast_sockaddr imagesa;
+ struct ast_sockaddr *sa = NULL; /*!< RTP Audio host IP */
+ struct ast_sockaddr *vsa = NULL; /*!< RTP video host IP */
+ struct ast_sockaddr *tsa = NULL; /*!< RTP text host IP */
+ struct ast_sockaddr *isa = NULL; /*!< UDPTL host ip */
int portno = -1; /*!< RTP Audio port number */
int vportno = -1; /*!< RTP Video port number */
int tportno = -1; /*!< RTP Text port number */
int udptlportno = -1; /*!< UDPTL Image port number */
- struct sockaddr_in sin; /*!< media socket address */
- struct sockaddr_in vsin; /*!< video socket address */
struct sockaddr_in isin; /*!< image socket address */
- struct sockaddr_in tsin; /*!< text socket address */
/* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */
format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0;
@@ -7741,12 +7757,12 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
return (p->session_modify == FALSE) ? 0 : -1;
break;
case 'c':
- if (process_sdp_c(value, &sessionhp)) {
+ if (process_sdp_c(value, &sessionsa)) {
processed = TRUE;
- hp = &sessionhp.hp;
- vhp = hp;
- thp = hp;
- ihp = hp;
+ sa = &sessionsa;
+ vsa = sa;
+ tsa = sa;
+ isa = sa;
}
break;
case 'a':
@@ -7891,24 +7907,24 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
switch (type) {
case 'c':
if (audio) {
- if (process_sdp_c(value, &audiohp)) {
+ if (process_sdp_c(value, &audiosa)) {
processed = TRUE;
- hp = &audiohp.hp;
+ sa = &audiosa;
}
} else if (video) {
- if (process_sdp_c(value, &videohp)) {
+ if (process_sdp_c(value, &videosa)) {
processed = TRUE;
- vhp = &videohp.hp;
+ vsa = &videosa;
}
} else if (text) {
- if (process_sdp_c(value, &texthp)) {
+ if (process_sdp_c(value, &textsa)) {
processed = TRUE;
- thp = &texthp.hp;
+ tsa = &textsa;
}
} else if (image) {
- if (process_sdp_c(value, &imagehp)) {
+ if (process_sdp_c(value, &imagesa)) {
processed = TRUE;
- ihp = &imagehp.hp;
+ isa = &imagesa;
}
}
break;
@@ -7956,7 +7972,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
/* Sanity checks */
- if (!hp && !vhp && !thp && !ihp) {
+ if (!sa && !vsa && !tsa && !isa) {
ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n");
return -1;
}
@@ -8042,13 +8058,13 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
/* Setup audio address and port */
if (p->rtp) {
if (portno > 0) {
- sin.sin_family = AF_INET;
- sin.sin_port = htons(portno);
- memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
- ast_rtp_instance_set_remote_address(p->rtp, &sin);
- if (debug)
- ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since
+ ast_sockaddr_set_port(sa, portno);
+ ast_rtp_instance_set_remote_address(p->rtp, sa);
+ if (debug) {
+ ast_verbose("Peer audio RTP is at port %s\n",
+ ast_sockaddr_stringify(sa));
+ }
+ /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since
they are acceptable */
p->jointcapability = newjointcapability; /* Our joint codec profile for this call */
p->peercapability = newpeercapability; /* The other sides capability in latest offer */
@@ -8085,12 +8101,12 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
/* Setup video address and port */
if (p->vrtp) {
if (vportno > 0) {
- vsin.sin_family = AF_INET;
- vsin.sin_port = htons(vportno);
- memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr));
- ast_rtp_instance_set_remote_address(p->vrtp, &vsin);
- if (debug)
- ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port));
+ ast_sockaddr_set_port(vsa, vportno);
+ ast_rtp_instance_set_remote_address(p->vrtp, vsa);
+ if (debug) {
+ ast_verbose("Peer video RTP is at port %s\n",
+ ast_sockaddr_stringify(vsa));
+ }
ast_rtp_codecs_payloads_copy(&newvideortp, ast_rtp_instance_get_codecs(p->vrtp), p->vrtp);
} else {
ast_rtp_instance_stop(p->vrtp);
@@ -8102,12 +8118,12 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
/* Setup text address and port */
if (p->trtp) {
if (tportno > 0) {
- tsin.sin_family = AF_INET;
- tsin.sin_port = htons(tportno);
- memcpy(&tsin.sin_addr, thp->h_addr, sizeof(tsin.sin_addr));
- ast_rtp_instance_set_remote_address(p->trtp, &tsin);
- if (debug)
- ast_verbose("Peer T.140 RTP is at port %s:%d\n", ast_inet_ntoa(tsin.sin_addr), ntohs(tsin.sin_port));
+ ast_sockaddr_set_port(tsa, tportno);
+ ast_rtp_instance_set_remote_address(p->trtp, tsa);
+ if (debug) {
+ ast_verbose("Peer T.140 RTP is at port %s\n",
+ ast_sockaddr_stringify(tsa));
+ }
if ((p->jointcapability & AST_FORMAT_T140RED)) {
p->red = 1;
ast_rtp_red_init(p->trtp, 300, red_data_pt, 2);
@@ -8128,7 +8144,12 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
isin.sin_port = htons(udptlportno);
if (ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) {
struct sockaddr_in remote_address = { 0, };
- ast_rtp_instance_get_remote_address(p->rtp, &remote_address);
+ struct ast_sockaddr remote_address_tmp;
+
+ ast_rtp_instance_get_remote_address(p->rtp,
+ &remote_address_tmp);
+ ast_sockaddr_to_sin(&remote_address_tmp,
+ &remote_address);
if (remote_address.sin_addr.s_addr) {
memcpy(&isin, &remote_address, sizeof(isin));
if (debug) {
@@ -8136,7 +8157,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
}
}
} else {
- memcpy(&isin.sin_addr, ihp->h_addr, sizeof(isin.sin_addr));
+ ast_sockaddr_to_sin(isa, &isin);
}
ast_udptl_set_peer(p->udptl, &isin);
if (debug)
@@ -8207,7 +8228,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
ast_set_write_format(p->owner, p->owner->writeformat);
}
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) {
+ if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && !ast_sockaddr_isnull(sa) && (!sendonly || sendonly == -1)) {
ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
/* Activate a re-invite */
ast_queue_frame(p->owner, &ast_null_frame);
@@ -8223,7 +8244,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
if (sip_cfg.notifyhold)
sip_peer_hold(p, FALSE);
ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
- } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) {
+ } else if (ast_sockaddr_isnull(sa) || (sendonly && sendonly != -1)) {
int already_on_hold = ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD);
ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
S_OR(p->mohsuggest, NULL),
@@ -8335,21 +8356,29 @@ static int process_sdp_o(const char *o, struct sip_pvt *p)
return TRUE;
}
-static int process_sdp_c(const char *c, struct ast_hostent *ast_hp)
+static int process_sdp_c(const char *c, struct ast_sockaddr *addr)
{
- char host[258];
- struct hostent *hp;
+ char proto[4], host[258];
+ int af;
/* Check for Media-description-level-address */
- if (sscanf(c, "IN IP4 %255s", host) != 1) {
- ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
- return FALSE;
- } else {
- if (!(hp = ast_gethostbyname(host, ast_hp))) {
+ if (sscanf(c, "IN %3s %255s", proto, host) == 2) {
+ if (!strcmp("IP4", proto)) {
+ af = AF_INET;
+ } else if (!strcmp("IP6", proto)) {
+ af = AF_INET6;
+ } else {
+ ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto);
+ return FALSE;
+ }
+ if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) {
ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c);
return FALSE;
}
return TRUE;
+ } else {
+ ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
+ return FALSE;
}
return FALSE;
}
@@ -8791,13 +8820,13 @@ static int copy_via_headers(struct sip_pvt *p, struct sip_request *req, const st
/* Add rport to first VIA header if requested */
snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
- leftmost, ast_inet_ntoa(p->recv.sin_addr),
- ntohs(p->recv.sin_port),
+ leftmost, ast_sockaddr_stringify_addr(&p->recv),
+ ast_sockaddr_port(&p->recv),
others ? "," : "", others ? others : "");
} else {
/* We should *always* add a received to the topmost via */
snprintf(new, sizeof(new), "%s;received=%s%s%s",
- leftmost, ast_inet_ntoa(p->recv.sin_addr),
+ leftmost, ast_sockaddr_stringify_addr(&p->recv),
others ? "," : "", others ? others : "");
}
oh = new; /* the header to copy */
@@ -8852,12 +8881,9 @@ static void add_route(struct sip_request *req, struct sip_route *route)
static void set_destination(struct sip_pvt *p, char *uri)
{
char *h, *maddr, hostname[256];
- int port, hn;
- struct hostent *hp;
- struct ast_hostent ahp;
+ int hn;
int debug=sip_debug_test_pvt(p);
int tls_on = FALSE;
- int use_dns = sip_cfg.srvlookup;
if (debug)
ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
@@ -8875,44 +8901,53 @@ static void set_destination(struct sip_pvt *p, char *uri)
tls_on = TRUE;
}
}
- hn = strcspn(h, ":;>") + 1;
+ hn = strcspn(h, ";>") + 1;
if (hn > sizeof(hostname))
hn = sizeof(hostname);
ast_copy_string(hostname, h, hn);
/* XXX bug here if string has been trimmed to sizeof(hostname) */
h += hn - 1;
- /* Is "port" present? if not default to STANDARD_SIP_PORT */
- if (*h == ':') {
- /* Parse port */
- ++h;
- port = strtol(h, &h, 10);
- use_dns = FALSE;
- } else
- port = tls_on ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
+ /*! \todo XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV,
+ * otherwise, just look for A records */
+ if (ast_sockaddr_resolve_first(&p->sa, hostname, 0)) {
+ ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
+ return;
+ }
- /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
+ /* Got the hostname - but maybe there's a "maddr=" to override address? */
maddr = strstr(h, "maddr=");
if (maddr) {
+ int port;
+
maddr += 6;
- hn = strspn(maddr, "0123456789.") + 1;
+ hn = strspn(maddr, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789-.:[]") + 1;
if (hn > sizeof(hostname))
hn = sizeof(hostname);
ast_copy_string(hostname, maddr, hn);
+
+ port = ast_sockaddr_port(&p->sa);
+
+ /*! \todo XXX If we have sip_cfg.srvlookup on, then look for
+ * NAPTR/SRV, otherwise, just look for A records */
+ if (ast_sockaddr_resolve_first(&p->sa, hostname, PARSE_PORT_FORBID)) {
+ ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
+ return;
+ }
+
+ ast_sockaddr_set_port(&p->sa, port);
}
- /*! \todo XXX If we have use_dns on, then look for NAPTR/SRV, otherwise, just look for A records */
-
- hp = ast_gethostbyname(hostname, &ahp);
- if (hp == NULL) {
- ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
- return;
+ if (!ast_sockaddr_port(&p->sa)) {
+ ast_sockaddr_set_port(&p->sa, tls_on ?
+ STANDARD_TLS_PORT : STANDARD_SIP_PORT);
+ }
+
+ if (debug) {
+ ast_verbose("set_destination: set destination to %s\n",
+ ast_sockaddr_stringify(&p->sa));
}
- p->sa.sin_family = AF_INET;
- memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
- p->sa.sin_port = htons(port);
- if (debug)
- ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
}
/*! \brief Initialize SIP response, based on SIP request */
@@ -9320,7 +9355,7 @@ static void temp_pvt_cleanup(void *data)
}
/*! \brief Transmit response, no retransmits, using a temporary pvt structure */
-static int transmit_response_using_temp(ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
+static int transmit_response_using_temp(ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
{
struct sip_pvt *p = NULL;
@@ -9339,20 +9374,20 @@ static int transmit_response_using_temp(ast_string_field callid, struct sockaddr
/* Initialize the bare minimum */
p->method = intended_method;
- if (!sin)
- p->ourip = internip;
- else {
- p->sa = *sin;
- ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
+ if (!addr) {
+ ast_sockaddr_copy(&p->ourip, &internip);
+ } else {
+ ast_sockaddr_copy(&p->sa, addr);
+ ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
}
p->branch = ast_random();
make_our_tag(p->tag, sizeof(p->tag));
p->ocseq = INITIAL_CSEQ;
- if (useglobal_nat && sin) {
+ if (useglobal_nat && addr) {
ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT);
- p->recv = *sin;
+ ast_sockaddr_copy(&p->recv, addr);
do_setnat(p);
}
@@ -9620,7 +9655,7 @@ static int add_rpid(struct sip_request *req, struct sip_pvt *p)
return 0;
if (ast_strlen_zero(lid_name))
lid_name = lid_num;
- fromdomain = S_OR(p->fromdomain, ast_strdupa(ast_inet_ntoa(p->ourip.sin_addr)));
+ fromdomain = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip));
lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 1);
@@ -9857,21 +9892,23 @@ static void add_noncodec_to_sdp(const struct sip_pvt *p, int format,
\note called from add_sdp()
*/
static void get_our_media_address(struct sip_pvt *p, int needvideo, int needtext,
- struct sockaddr_in *sin, struct sockaddr_in *vsin, struct sockaddr_in *tsin,
- struct sockaddr_in *dest, struct sockaddr_in *vdest, struct sockaddr_in *tdest)
+ struct ast_sockaddr *addr, struct ast_sockaddr *vaddr,
+ struct ast_sockaddr *taddr, struct ast_sockaddr *dest,
+ struct ast_sockaddr *vdest, struct ast_sockaddr *tdest)
{
/* First, get our address */
- ast_rtp_instance_get_local_address(p->rtp, sin);
- if (p->vrtp)
- ast_rtp_instance_get_local_address(p->vrtp, vsin);
- if (p->trtp)
- ast_rtp_instance_get_local_address(p->trtp, tsin);
+ ast_rtp_instance_get_local_address(p->rtp, addr);
+ if (p->vrtp) {
+ ast_rtp_instance_get_local_address(p->vrtp, vaddr);
+ }
+ if (p->trtp) {
+ ast_rtp_instance_get_local_address(p->trtp, taddr);
+ }
/* Now, try to figure out where we want them to send data */
/* Is this a re-invite to move the media out, then use the original offer from caller */
- if (p->redirip.sin_addr.s_addr) { /* If we have a redirection IP, use it */
- dest->sin_port = p->redirip.sin_port;
- dest->sin_addr = p->redirip.sin_addr;
+ if (!ast_sockaddr_isnull(&p->redirip)) { /* If we have a redirection IP, use it */
+ ast_sockaddr_copy(dest, &p->redirip);
} else {
/*
* Audio Destination IP:
@@ -9884,15 +9921,17 @@ static void get_our_media_address(struct sip_pvt *p, int needvideo, int needtext
*
* 1. Provided by the RTP engine.
*/
- dest->sin_addr = media_address.sin_addr.s_addr ? media_address.sin_addr :
- (sin->sin_addr.s_addr ? sin->sin_addr : p->ourip.sin_addr);
- dest->sin_port = sin->sin_port;
+ ast_sockaddr_copy(dest,
+ !ast_sockaddr_isnull(&media_address) ? &media_address :
+ !ast_sockaddr_is_any(addr) ? addr :
+ &p->ourip);
+ ast_sockaddr_set_port(dest, ast_sockaddr_port(addr));
}
+
if (needvideo) {
/* Determine video destination */
- if (p->vredirip.sin_addr.s_addr) {
- vdest->sin_addr = p->vredirip.sin_addr;
- vdest->sin_port = p->vredirip.sin_port;
+ if (!ast_sockaddr_isnull(&p->vredirip)) {
+ ast_sockaddr_copy(vdest, &p->vredirip);
} else {
/*
* Video Destination IP:
@@ -9905,16 +9944,18 @@ static void get_our_media_address(struct sip_pvt *p, int needvideo, int needtext
*
* 1. Provided by the RTP engine.
*/
- vdest->sin_addr = media_address.sin_addr.s_addr ? media_address.sin_addr :
- (vsin->sin_addr.s_addr ? vsin->sin_addr : p->ourip.sin_addr);
- vdest->sin_port = vsin->sin_port;
+ ast_sockaddr_copy(vdest,
+ !ast_sockaddr_isnull(&media_address) ? &media_address :
+ !ast_sockaddr_is_any(vaddr) ? vaddr :
+ &p->ourip);
+ ast_sockaddr_set_port(vdest, ast_sockaddr_port(vaddr));
}
}
+
if (needtext) {
/* Determine text destination */
- if (p->tredirip.sin_addr.s_addr) {
- tdest->sin_addr = p->tredirip.sin_addr;
- tdest->sin_port = p->tredirip.sin_port;
+ if (!ast_sockaddr_isnull(&p->tredirip)) {
+ ast_sockaddr_copy(tdest, &p->tredirip);
} else {
/*
* Text Destination IP:
@@ -9927,9 +9968,11 @@ static void get_our_media_address(struct sip_pvt *p, int needvideo, int needtext
*
* 1. Provided by the RTP engine.
*/
- tdest->sin_addr = media_address.sin_addr.s_addr ? media_address.sin_addr :
- (tsin->sin_addr.s_addr ? tsin->sin_addr : p->ourip.sin_addr);
- tdest->sin_port = tsin->sin_port;
+ ast_sockaddr_copy(tdest,
+ !ast_sockaddr_isnull(&media_address) ? &media_address :
+ !ast_sockaddr_is_any(taddr) ? taddr :
+ &p->ourip);
+ ast_sockaddr_set_port(tdest, ast_sockaddr_port(taddr));
}
}
}
@@ -9961,13 +10004,14 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
{
format_t alreadysent = 0;
- struct sockaddr_in sin = { 0, };
- struct sockaddr_in vsin = { 0, };
- struct sockaddr_in tsin = { 0, };
- struct sockaddr_in dest = { 0, };
+ struct ast_sockaddr addr = { {0,} };
+ struct ast_sockaddr vaddr = { {0,} };
+ struct ast_sockaddr taddr = { {0,} };
+ struct ast_sockaddr dest = { {0,} };
+ struct ast_sockaddr vdest = { {0,} };
+ struct ast_sockaddr tdest = { {0,} };
+ struct sockaddr_in dest_tmp;
struct sockaddr_in udptlsin = { 0, };
- struct sockaddr_in vdest = { 0, };
- struct sockaddr_in tdest = { 0, };
struct sockaddr_in udptldest = { 0, };
/* SDP fields */
@@ -10048,11 +10092,19 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
}
}
- get_our_media_address(p, needvideo, needtext, &sin, &vsin, &tsin, &dest, &vdest, &tdest);
+ get_our_media_address(p, needvideo, needtext, &addr, &vaddr, &taddr, &dest, &vdest, &tdest);
- snprintf(owner, sizeof(owner), "o=%s %d %d IN IP4 %s\r\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner, p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
+ snprintf(owner, sizeof(owner), "o=%s %d %d IN %s %s\r\n",
+ ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner,
+ p->sessionid, p->sessionversion,
+ (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ?
+ "IP6" : "IP4",
+ ast_sockaddr_stringify_addr(&dest));
- snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
+ snprintf(connection, sizeof(connection), "c=IN %s %s\r\n",
+ (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ?
+ "IP6" : "IP4",
+ ast_sockaddr_stringify_addr(&dest));
if (add_audio) {
capability = p->jointcapability;
@@ -10066,21 +10118,23 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
if (capability & AST_FORMAT_AUDIO_MASK)
needaudio = TRUE;
- if (debug)
- ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(sin.sin_port));
+ if (debug) {
+ ast_verbose("Audio is at %s\n", ast_sockaddr_stringify_port(&p->ourip));
+ }
/* Ok, we need video. Let's add what we need for video and set codecs.
Video is handled differently than audio since we can not transcode. */
if (needvideo) {
get_crypto_attrib(p->vsrtp, &v_a_crypto);
- ast_str_append(&m_video, 0, "m=video %d RTP/%s", ntohs(vdest.sin_port),
+ ast_str_append(&m_video, 0, "m=video %d RTP/%s", ast_sockaddr_port(&vdest),
v_a_crypto ? "SAVP" : "AVP");
/* Build max bitrate string */
if (p->maxcallbitrate)
snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
- if (debug)
- ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(vdest.sin_port));
+ if (debug) {
+ ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&p->ourip));
+ }
}
/* Ok, we need text. Let's add what we need for text and set codecs.
@@ -10089,11 +10143,11 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
if (sipdebug_text)
ast_verbose("Lets set up the text sdp\n");
get_crypto_attrib(p->tsrtp, &t_a_crypto);
- ast_str_append(&m_text, 0, "m=text %d RTP/%s", ntohs(tdest.sin_port),
+ ast_str_append(&m_text, 0, "m=text %d RTP/%s", ast_sockaddr_port(&tdest),
t_a_crypto ? "SAVP" : "AVP");
- if (debug) /* XXX should I use tdest below ? */
- ast_verbose("Text is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(tsin.sin_port));
-
+ if (debug) { /* XXX should I use tdest below ? */
+ ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&p->ourip));
+ }
}
/* Start building generic SDP headers */
@@ -10102,7 +10156,7 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
peer doesn't have to ast_gethostbyname() us */
get_crypto_attrib(p->srtp, &a_crypto);
- ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ntohs(dest.sin_port),
+ ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest),
a_crypto ? "SAVP" : "AVP");
if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
@@ -10200,19 +10254,21 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
udptldest.sin_port = p->udptlredirip.sin_port;
udptldest.sin_addr = p->udptlredirip.sin_addr;
} else {
- udptldest.sin_addr = p->ourip.sin_addr;
+ ast_sockaddr_to_sin(&p->ourip, &udptldest);
udptldest.sin_port = udptlsin.sin_port;
}
- if (debug)
- ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(udptlsin.sin_port));
+ if (debug) {
+ ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_sockaddr_stringify_addr(&p->ourip), ntohs(udptlsin.sin_port));
+ }
/* We break with the "recommendation" and send our IP, in order that our
peer doesn't have to ast_gethostbyname() us */
ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
- if (udptldest.sin_addr.s_addr != dest.sin_addr.s_addr) {
+ ast_sockaddr_to_sin(&dest, &dest_tmp);
+ if (udptldest.sin_addr.s_addr != dest_tmp.sin_addr.s_addr) {
ast_str_append(&m_modem, 0, "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr));
}
@@ -10551,19 +10607,13 @@ static void extract_uri(struct sip_pvt *p, struct sip_request *req)
/*! \brief Build contact header - the contact header we send out */
static void build_contact(struct sip_pvt *p)
{
-
- int ourport = ntohs(p->ourip.sin_port);
- /* only add port if it's non-standard for the transport type */
- if (!sip_standard_port(p->socket.type, ourport)) {
- if (p->socket.type == SIP_TRANSPORT_UDP)
- ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr), ourport);
- else
- ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d;transport=%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr), ourport, get_transport(p->socket.type));
+ if (p->socket.type == SIP_TRANSPORT_UDP) {
+ ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten,
+ ast_strlen_zero(p->exten) ? "" : "@", ast_sockaddr_stringify(&p->ourip));
} else {
- if (p->socket.type == SIP_TRANSPORT_UDP)
- ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr));
- else
- ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr), get_transport(p->socket.type));
+ ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", p->exten,
+ ast_strlen_zero(p->exten) ? "" : "@", ast_sockaddr_stringify(&p->ourip),
+ get_transport(p->socket.type));
}
}
@@ -10603,7 +10653,7 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
- d = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr));
+ d = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip));
if (p->owner && (p->owner->connected.id.number_presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
l = p->owner->connected.id.number;
n = p->owner->connected.id.name;
@@ -10647,13 +10697,12 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
l = tmp_l;
}
- ourport = (p->fromdomainport) ? p->fromdomainport : ntohs(p->ourip.sin_port);
+ ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip);
if (!sip_standard_port(p->socket.type, ourport))
snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag);
else
snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag);
-
if (!ast_strlen_zero(explicit_uri)) {
ast_str_set(&invite, 0, "%s", explicit_uri);
} else {
@@ -10673,8 +10722,9 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
ast_str_append(&invite, 0, "%s@", n);
}
ast_str_append(&invite, 0, "%s", p->tohost);
- if (p->portinuri)
- ast_str_append(&invite, 0, ":%d", ntohs(p->sa.sin_port));
+ if (p->portinuri) {
+ ast_str_append(&invite, 0, ":%d", ast_sockaddr_port(&p->sa));
+ }
ast_str_append(&invite, 0, "%s", urioptions);
}
}
@@ -10759,9 +10809,12 @@ static void add_diversion_header(struct sip_request *req, struct sip_pvt *pvt)
/* We at least have a number to place in the Diversion header, which is enough */
if (ast_strlen_zero(diverting_name)) {
- snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number, ast_inet_ntoa(pvt->ourip.sin_addr), reason);
+ snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number,
+ ast_sockaddr_stringify_host(&pvt->ourip), reason);
} else {
- snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s", diverting_name, diverting_number, ast_inet_ntoa(pvt->ourip.sin_addr), reason);
+ snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s",
+ diverting_name, diverting_number,
+ ast_sockaddr_stringify_host(&pvt->ourip), reason);
}
add_header(req, "Diversion", header_text);
@@ -10784,7 +10837,7 @@ static int transmit_publish(struct sip_epa_entry *epa_entry, enum sip_publish_ty
dialog_unlink_all(pvt, TRUE, TRUE);
dialog_unref(pvt, "create_addr failed in transmit_publish. Unref dialog");
}
- ast_sip_ouraddrfor(&pvt->sa.sin_addr, &pvt->ourip, pvt);
+ ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt);
ast_set_flag(&pvt->flags[0], SIP_OUTGOING);
expires = (publish_type == SIP_PUBLISH_REMOVE) ? 0 : DEFAULT_PUBLISH_EXPIRES;
pvt->expiry = expires;
@@ -10986,6 +11039,8 @@ static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi)
if (!mwi->dnsmgr) {
char transport[MAXHOSTNAMELEN];
snprintf(transport, sizeof(transport), "_sip._%s", get_transport(mwi->transport));
+
+ mwi->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
ast_dnsmgr_lookup(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL);
}
@@ -11002,8 +11057,8 @@ static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi)
ref_proxy(mwi->call, obproxy_get(mwi->call, NULL));
- if (!mwi->us.sin_port && mwi->portno) {
- mwi->us.sin_port = htons(mwi->portno);
+ if (!ast_sockaddr_port(&mwi->us) && mwi->portno) {
+ ast_sockaddr_set_port(&mwi->us, mwi->portno);
}
/* Setup the destination of our subscription */
@@ -11016,10 +11071,10 @@ static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi)
mwi->call->expiry = mwi_expiry;
if (!mwi->dnsmgr && mwi->portno) {
- mwi->call->sa.sin_port = htons(mwi->portno);
- mwi->call->recv.sin_port = htons(mwi->portno);
+ ast_sockaddr_set_port(&mwi->call->sa, mwi->portno);
+ ast_sockaddr_set_port(&mwi->call->recv, mwi->portno);
} else {
- mwi->portno = ntohs(mwi->call->sa.sin_port);
+ mwi->portno = ast_sockaddr_port(&mwi->call->sa);
}
/* Set various other information */
@@ -11038,7 +11093,7 @@ static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi)
}
set_socket_transport(&mwi->call->socket, mwi->transport);
mwi->call->socket.port = htons(mwi->portno);
- ast_sip_ouraddrfor(&mwi->call->sa.sin_addr, &mwi->call->ourip, mwi->call);
+ ast_sip_ouraddrfor(&mwi->call->sa, &mwi->call->ourip, mwi->call);
build_contact(mwi->call);
build_via(mwi->call);
build_callid_pvt(mwi->call);
@@ -11353,8 +11408,8 @@ static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs,
{
struct sip_request req;
struct ast_str *out = ast_str_alloca(500);
- int ourport = (p->fromdomainport) ? p->fromdomainport : ntohs(p->ourip.sin_port);
- const char *domain = S_OR(p->fromdomain,ast_inet_ntoa(p->ourip.sin_addr));
+ int ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip);
+ const char *domain = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip));
const char *exten = S_OR(vmexten, default_vmexten);
initreqprep(&req, p, SIP_NOTIFY, NULL);
@@ -11697,6 +11752,7 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
char transport[MAXHOSTNAMELEN];
peer = find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0);
snprintf(transport, sizeof(transport), "_sip._%s", get_transport(r->transport)); /* have to use static get_transport function */
+ r->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
ast_dnsmgr_lookup(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL);
if (peer) {
peer = unref_peer(peer, "removing peer ref for dnsmgr_lookup");
@@ -11715,7 +11771,7 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
} else {
/* Build callid for registration if we haven't registered before */
if (!r->callid_valid) {
- build_callid_registry(r, internip.sin_addr, default_fromdomain);
+ build_callid_registry(r, &internip, default_fromdomain);
r->callid_valid = TRUE;
}
/* Allocate SIP dialog for registration */
@@ -11728,8 +11784,9 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
/* Use port number specified if no SRV record was found */
- if (!r->us.sin_port && r->portno)
- r->us.sin_port = htons(r->portno);
+ if (!ast_sockaddr_port(&r->us) && r->portno) {
+ ast_sockaddr_set_port(&r->us, r->portno);
+ }
/* Find address to hostname */
if (create_addr(p, S_OR(r->peername, r->hostname), &r->us, 0, NULL)) {
@@ -11755,15 +11812,15 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
ast_string_field_set(r, callid, p->callid);
if (!r->dnsmgr && r->portno) {
- p->sa.sin_port = htons(r->portno);
- p->recv.sin_port = htons(r->portno);
+ ast_sockaddr_set_port(&p->sa, r->portno);
+ ast_sockaddr_set_port(&p->recv, r->portno);
}
if (!ast_strlen_zero(p->fromdomain)) {
portno = (p->fromdomainport) ? p->fromdomainport : STANDARD_SIP_PORT;
} else if (!ast_strlen_zero(r->regdomain)) {
portno = (r->regdomainport) ? r->regdomainport : STANDARD_SIP_PORT;
} else {
- portno = ntohs(p->sa.sin_port);
+ portno = ast_sockaddr_port(&p->sa);
}
ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
@@ -11793,7 +11850,8 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
/* Set transport and port so the correct contact is built */
set_socket_transport(&p->socket, r->transport);
if (r->transport == SIP_TRANSPORT_TLS || r->transport == SIP_TRANSPORT_TCP) {
- p->socket.port = sip_tcp_desc.local_address.sin_port;
+ p->socket.port =
+ htons(ast_sockaddr_port(&sip_tcp_desc.local_address));
}
/*
@@ -11801,7 +11859,7 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
based on whether the remote host is on the external or
internal network so we can register through nat
*/
- ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
+ ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
build_contact(p);
}
@@ -12196,7 +12254,7 @@ static int expire_register(const void *data)
if (peer->selfdestruct ||
ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table");
- if (peer->addr.sin_addr.s_addr) {
+ if (!ast_sockaddr_isnull(&peer->addr)) {
ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
}
}
@@ -12224,30 +12282,28 @@ static int sip_poke_peer_s(const void *data)
static void reg_source_db(struct sip_peer *peer)
{
char data[256];
- struct in_addr in;
+ struct ast_sockaddr sa;
int expire;
- int port;
- char *scan, *addr, *port_str, *expiry_str, *username, *contact;
+ char *scan, *addr, *expiry_str, *username, *contact;
if (peer->rt_fromcontact)
return;
if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
return;
- scan = data;
- addr = strsep(&scan, ":");
- port_str = strsep(&scan, ":");
+ addr = scan = data;
+ if ('[' == scan[0]) {
+ /* It must be a bracket enclosed IPv6 address */
+ scan = strchr(scan, ']') + 1;
+ }
+ scan = strchr(scan, ':') + 1;
expiry_str = strsep(&scan, ":");
username = strsep(&scan, ":");
contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
- if (!inet_aton(addr, &in))
- return;
-
- if (port_str)
- port = atoi(port_str);
- else
+ if (!ast_sockaddr_parse(&sa, addr, 0)) {
return;
+ }
if (expiry_str)
expire = atoi(expiry_str);
@@ -12259,13 +12315,10 @@ static void reg_source_db(struct sip_peer *peer)
if (contact)
ast_string_field_set(peer, fullcontact, contact);
- ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
- peer->name, peer->username, ast_inet_ntoa(in), port, expire);
+ ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s for %d\n",
+ peer->name, peer->username, ast_sockaddr_stringify_host(&sa), expire);
- memset(&peer->addr, 0, sizeof(peer->addr));
- peer->addr.sin_family = AF_INET;
- peer->addr.sin_addr = in;
- peer->addr.sin_port = htons(port);
+ ast_sockaddr_copy(&peer->addr, &sa);
if (sipsock < 0) {
/* SIP isn't up yet, so schedule a poke only, pretty soon */
AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer,
@@ -12303,12 +12356,9 @@ static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req)
return TRUE;
}
-static int __set_address_from_contact(const char *fullcontact, struct sockaddr_in *sin, int tcp)
+static int __set_address_from_contact(const char *fullcontact, struct ast_sockaddr *addr, int tcp)
{
- struct hostent *hp;
- struct ast_hostent ahp;
- int port = STANDARD_SIP_PORT;
- char *host, *pt, *transport;
+ char *domain, *transport;
char contact_buf[256];
char *contact;
@@ -12323,32 +12373,32 @@ static int __set_address_from_contact(const char *fullcontact, struct sockaddr_i
* We still need to be able to send to the remote agent through the proxy.
*/
- if (parse_uri(contact, "sip:,sips:", &contact, NULL, &host, &pt, &transport)) {
+ if (parse_uri(contact, "sip:,sips:", &contact, NULL, &domain,
+ &transport)) {
ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact);
}
- /* set port */
- if (((get_transport_str2enum(transport) == SIP_TRANSPORT_TLS)) || !(strncasecmp(fullcontact, "sips", 4))) {
- port = port_str2int(pt, STANDARD_TLS_PORT);
- } else {
- port = port_str2int(pt, STANDARD_SIP_PORT);
- }
-
-
/* XXX This could block for a long time XXX */
/* We should only do this if it's a name, not an IP */
/* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records
to find transport, port address and hostname. If there's a port number, we have to
assume that the domain part is a host name and only look for an A/AAAA record in DNS.
*/
- hp = ast_gethostbyname(host, &ahp);
- if (!hp) {
- ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
+
+ if (ast_sockaddr_resolve_first(addr, domain, 0)) {
+ ast_log(LOG_WARNING, "Invalid host name in Contact: (can't "
+ "resolve in DNS) : '%s'\n", domain);
return -1;
}
- sin->sin_family = AF_INET;
- memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
- sin->sin_port = htons(port);
+
+ /* set port */
+ if (!ast_sockaddr_port(addr)) {
+ ast_sockaddr_set_port(addr,
+ (get_transport_str2enum(transport) ==
+ SIP_TRANSPORT_TLS ||
+ !strncasecmp(fullcontact, "sips", 4)) ?
+ STANDARD_TLS_PORT : STANDARD_SIP_PORT);
+ }
return 0;
}
@@ -12374,14 +12424,11 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
char data[SIPBUFSIZE];
const char *expires = get_header(req, "Expires");
int expire = atoi(expires);
- char *curi, *host, *pt, *transport;
- int port;
+ char *curi, *domain, *transport;
int transport_type;
const char *useragent;
- struct hostent *hp;
- struct ast_hostent ahp;
- struct sockaddr_in oldsin, testsin;
-
+ struct ast_sockaddr oldsin, testsa;
+ struct sockaddr_in testsin;
ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
@@ -12445,23 +12492,12 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
ast_string_field_build(pvt, our_contact, "<%s>", curi);
/* Make sure it's a SIP URL */
- if (parse_uri(curi, "sip:,sips:", &curi, NULL, &host, &pt, &transport)) {
+ if (parse_uri(curi, "sip:,sips:", &curi, NULL, &domain, &transport)) {
ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:) trying to use anyway\n");
}
- /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records.
- The domain part is actually a host. */
- peer->portinuri = !ast_strlen_zero(pt) ? TRUE : FALSE;
-
/* handle the transport type specified in Contact header. */
- if ((transport_type = get_transport_str2enum(transport))) {
- /* if the port is not specified but the transport is, make sure to set the
- * default port to match the specified transport. This may or may not be the
- * same transport used by the pvt struct for the Register dialog. */
-
- port = port_str2int(pt, (transport_type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT);
- } else {
- port = port_str2int(pt, STANDARD_SIP_PORT);
+ if (!(transport_type = get_transport_str2enum(transport))) {
transport_type = pvt->socket.type;
}
@@ -12475,25 +12511,32 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
oldsin = peer->addr;
/* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */
- if (peer->addr.sin_addr.s_addr) {
+ if (!ast_sockaddr_isnull(&peer->addr)) {
ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
}
if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT)) {
- /* use the data provided in the Contact header for call routing */
+ /* use the data provided in the Contact header for call routing */
ast_debug(1, "Store REGISTER's Contact header for call routing.\n");
/* XXX This could block for a long time XXX */
/*! \todo Check NAPTR/SRV if we have not got a port in the URI */
- hp = ast_gethostbyname(host, &ahp);
- if (!hp) {
- ast_log(LOG_WARNING, "Invalid host '%s'\n", host);
+ if (ast_sockaddr_resolve_first(&testsa, domain, 0)) {
+ ast_log(LOG_WARNING, "Invalid domain '%s'\n", domain);
ast_string_field_set(peer, fullcontact, "");
ast_string_field_set(pvt, our_contact, "");
return PARSE_REGISTER_FAILED;
}
- peer->addr.sin_family = AF_INET;
- memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
- peer->addr.sin_port = htons(port);
+ ast_sockaddr_copy(&peer->addr, &testsa);
+
+ /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records.
+ The domain part is actually a host. */
+ peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE;
+
+ if (!ast_sockaddr_port(&testsa)) {
+ ast_sockaddr_set_port(&testsa,
+ transport_type == SIP_TRANSPORT_TLS ?
+ STANDARD_TLS_PORT : STANDARD_SIP_PORT);
+ }
} else {
/* Don't trust the contact field. Just use what they came to us
with */
@@ -12502,22 +12545,23 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
}
/* Check that they're allowed to register at this IP */
- memcpy(&testsin.sin_addr, &peer->addr.sin_addr, sizeof(testsin.sin_addr));
- if (ast_apply_ha(sip_cfg.contact_ha, &testsin) != AST_SENSE_ALLOW ||
- ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) {
- ast_log(LOG_WARNING, "Host '%s' disallowed by contact ACL (violating IP %s)\n", host, ast_inet_ntoa(testsin.sin_addr));
- ast_string_field_set(peer, fullcontact, "");
- ast_string_field_set(pvt, our_contact, "");
- return PARSE_REGISTER_DENIED;
+ if (!ast_sockaddr_is_ipv6(&peer->addr)) {
+ ast_sockaddr_to_sin(&peer->addr, &testsin);
+ if (ast_apply_ha(sip_cfg.contact_ha, &testsin) != AST_SENSE_ALLOW ||
+ ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) {
+ ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", domain,
+ ast_sockaddr_stringify_addr(&testsa));
+ ast_string_field_set(peer, fullcontact, "");
+ ast_string_field_set(pvt, our_contact, "");
+ return PARSE_REGISTER_DENIED;
+ }
}
/* if the Contact header information copied into peer->addr matches the
* received address, and the transport types are the same, then copy socket
* data into the peer struct */
if ((peer->socket.type == pvt->socket.type) &&
- (peer->addr.sin_addr.s_addr == pvt->recv.sin_addr.s_addr) &&
- (peer->addr.sin_port == pvt->recv.sin_port)){
-
+ !ast_sockaddr_cmp(&peer->addr, &pvt->recv)) {
copy_socket_data(&peer->socket, &pvt->socket);
}
@@ -12547,18 +12591,20 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
}
}
pvt->expiry = expire;
- snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port), expire, peer->username, peer->fullcontact);
+ snprintf(data, sizeof(data), "%s:%d:%s:%s", ast_sockaddr_stringify(&peer->addr),
+ expire, peer->username, peer->fullcontact);
/* Saving TCP connections is useless, we won't be able to reconnect
XXX WHY???? XXX
\todo Fix this immediately.
*/
if (!peer->rt_fromcontact && (peer->socket.type & SIP_TRANSPORT_UDP))
ast_db_put("SIP/Registry", peer->name, data);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPort: %d\r\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port));
+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name, ast_sockaddr_stringify(&peer->addr));
/* Is this a new IP address for us? */
- if (VERBOSITY_ATLEAST(2) && inaddrcmp(&peer->addr, &oldsin)) {
- ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port));
+ if (VERBOSITY_ATLEAST(2) && ast_sockaddr_cmp(&peer->addr, &oldsin)) {
+ ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s\n", peer->name,
+ ast_sockaddr_stringify(&peer->addr));
}
sip_poke_peer(peer, 0);
register_peer_exten(peer, 1);
@@ -13084,7 +13130,7 @@ static char *terminate_uri(char *uri)
to get a challenge (nonce) then a second one with auth
- Registration requests are only matched with peers that are marked as "dynamic"
*/
-static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr_in *sin,
+static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sockaddr *addr,
struct sip_request *req, const char *uri)
{
enum check_auth_result res = AUTH_NOT_FOUND;
@@ -13100,8 +13146,8 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
c = get_in_brackets(tmp);
c = remove_uri_parameters(c);
- if (parse_uri(c, "sip:,sips:", &name, &dummy, &domain, &dummy, NULL)) {
- ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
+ if (parse_uri(c, "sip:,sips:", &name, &dummy, &domain, NULL)) {
+ ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_sockaddr_stringify_addr(addr));
return -1;
}
@@ -13136,14 +13182,20 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
}
}
peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0);
- if (!(peer && ast_apply_ha(peer->ha, sin))) {
- /* Peer fails ACL check */
- if (peer) {
- unref_peer(peer, "register_verify: unref_peer: from find_peer operation");
- peer = NULL;
- res = AUTH_ACL_FAILED;
- } else
- res = AUTH_NOT_FOUND;
+
+ if (!ast_sockaddr_is_ipv6(addr)) {
+ struct sockaddr_in sin_tmp;
+
+ ast_sockaddr_to_sin(addr, &sin_tmp);
+ if (!(peer && ast_apply_ha(peer->ha, &sin_tmp))) {
+ /* Peer fails ACL check */
+ if (peer) {
+ unref_peer(peer, "register_verify: unref_peer: from find_peer operation");
+ peer = NULL;
+ res = AUTH_ACL_FAILED;
+ } else
+ res = AUTH_NOT_FOUND;
+ }
}
if (peer) {
@@ -13207,7 +13259,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
peer = temp_peer(name);
if (peer) {
ao2_t_link(peers, peer, "link peer into peer table");
- if (peer->addr.sin_addr.s_addr) {
+ if (!ast_sockaddr_isnull(&peer->addr)) {
ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table");
}
ao2_lock(peer);
@@ -13236,7 +13288,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
ast_string_field_set(p, fullcontact, peer->fullcontact);
/* Say OK and ask subsystem to retransmit msg counter */
transmit_response_with_date(p, "200 OK", req);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPort: %d\r\n", peer->name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name, ast_sockaddr_stringify(addr));
peer->lastmsgssent = -1;
res = 0;
break;
@@ -13260,9 +13312,17 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
case AUTH_SECRET_FAILED:
/* Wrong password in authentication. Go away, don't try again until you fixed it */
transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
- if (global_authfailureevents)
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Rejected\r\nCause: AUTH_SECRET_FAILED\r\nAddress: %s\r\nPort: %d\r\n",
- name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+ if (global_authfailureevents) {
+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
+ "ChannelType: SIP\r\n"
+ "Peer: SIP/%s\r\n"
+ "PeerStatus: Rejected\r\n"
+ "Cause: AUTH_SECRET_FAILED\r\n"
+ "Address: %s\r\n"
+ "Port: %s\r\n",
+ name, ast_sockaddr_stringify_addr(addr),
+ ast_sockaddr_stringify_port(addr));
+ }
break;
case AUTH_USERNAME_MISMATCH:
/* Username and digest username does not match.
@@ -13275,9 +13335,17 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
if (sip_cfg.alwaysauthreject) {
transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE);
if (global_authfailureevents) {
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Rejected\r\nCause: %s\r\nAddress: %s\r\nPort: %d\r\n",
- name, res == AUTH_PEER_NOT_DYNAMIC ? "AUTH_PEER_NOT_DYNAMIC" : "URI_NOT_FOUND",
- ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
+ "ChannelType: SIP\r\n"
+ "Peer: SIP/%s\r\n"
+ "PeerStatus: Rejected\r\n"
+ "Cause: %s\r\n"
+ "Address: %s\r\n"
+ "Port: %s\r\n",
+ name,
+ res == AUTH_PEER_NOT_DYNAMIC ? "AUTH_PEER_NOT_DYNAMIC" : "URI_NOT_FOUND",
+ ast_sockaddr_stringify_addr(addr),
+ ast_sockaddr_stringify_port(addr));
}
} else {
/* URI not found */
@@ -13290,8 +13358,10 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
"PeerStatus: Rejected\r\n"
"Cause: AUTH_PEER_NOT_DYNAMIC\r\n"
"Address: %s\r\n"
- "Port: %d\r\n",
- name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+ "Port: %s\r\n",
+ name,
+ ast_sockaddr_stringify_addr(addr),
+ ast_sockaddr_stringify_port(addr));
}
} else {
transmit_response(p, "404 Not found", &p->initreq);
@@ -13302,9 +13372,11 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
"PeerStatus: Rejected\r\n"
"Cause: %s\r\n"
"Address: %s\r\n"
- "Port: %d\r\n",
- name, (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND",
- ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+ "Port: %s\r\n",
+ name,
+ (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND",
+ ast_sockaddr_stringify_addr(addr),
+ ast_sockaddr_stringify_port(addr));
}
}
}
@@ -13645,7 +13717,7 @@ static enum sip_get_dest_result get_destination(struct sip_pvt *p, struct sip_re
uri = ast_strdupa(get_in_brackets(tmp));
- if (parse_uri(uri, "sip:,sips:", &uri, &dummy, &domain, &dummy, NULL)) {
+ if (parse_uri(uri, "sip:,sips:", &uri, &dummy, &domain, NULL)) {
ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri);
return SIP_GET_DEST_INVALID_URI;
}
@@ -13662,7 +13734,7 @@ static enum sip_get_dest_result get_destination(struct sip_pvt *p, struct sip_re
ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
if (!ast_strlen_zero(tmpf)) {
from = get_in_brackets(tmpf);
- if (parse_uri(from, "sip:,sips:", &from, NULL, &domain, NULL, NULL)) {
+ if (parse_uri(from, "sip:,sips:", &from, NULL, &domain, NULL)) {
ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from);
return SIP_GET_DEST_INVALID_URI;
}
@@ -14033,7 +14105,7 @@ static int get_also_info(struct sip_pvt *p, struct sip_request *oreq)
ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
c = get_in_brackets(tmp);
- if (parse_uri(c, "sip:,sips:", &c, NULL, &a, NULL, NULL)) {
+ if (parse_uri(c, "sip:,sips:", &c, NULL, &a, NULL)) {
ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c);
return -1;
}
@@ -14104,9 +14176,9 @@ static attribute_unused void check_via_response(struct sip_pvt *p, struct sip_re
if (!strncmp(cur, "rport=", 6)) {
int port = strtol(cur+6, NULL, 10);
/* XXX add error checking */
- p->ourip.sin_port = ntohs(port);
+ ast_sockaddr_set_port(&p->ourip, port);
} else if (!strncmp(cur, "received=", 9)) {
- if (ast_parse_arg(cur+9, PARSE_INADDR, &p->ourip))
+ if (ast_parse_arg(cur + 9, PARSE_ADDR, &p->ourip))
; /* XXX add error checking */
}
}
@@ -14127,14 +14199,17 @@ static void check_via(struct sip_pvt *p, struct sip_request *req)
/* Check for rport */
c = strstr(via, ";rport");
- if (c && (c[6] != '=')) /* rport query, not answer */
+ if (c && (c[6] != '=')) { /* rport query, not answer */
ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT);
+ ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT);
+ }
/* Check for maddr */
maddr = strstr(via, "maddr=");
if (maddr) {
maddr += 6;
- c = maddr + strspn(maddr, "0123456789.");
+ c = maddr + strspn(maddr, "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.:[]");
*c = '\0';
}
@@ -14144,9 +14219,6 @@ static void check_via(struct sip_pvt *p, struct sip_request *req)
c = strchr(via, ' ');
if (c) {
- struct hostent *hp;
- struct ast_hostent ahp;
-
*c = '\0';
c = ast_skip_blanks(c+1);
if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) {
@@ -14157,28 +14229,28 @@ static void check_via(struct sip_pvt *p, struct sip_request *req)
if (pt)
*pt++ = '\0'; /* remember port pointer */
- if (maddr && (hp = ast_gethostbyname(maddr, &ahp))) {
- memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
- } else {
+ if (maddr && ast_sockaddr_resolve_first(&p->sa, maddr, 0)) {
p->sa = p->recv;
}
- p->sa.sin_port = htons(port_str2int(pt, STANDARD_SIP_PORT));
+
+ ast_sockaddr_set_port(&p->sa, port_str2int(pt, STANDARD_SIP_PORT));
if (sip_debug_test_pvt(p)) {
- const struct sockaddr_in *dst = sip_real_dst(p);
- ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
+ ast_verbose("Sending to %s (%s)\n",
+ ast_sockaddr_stringify(sip_real_dst(p)),
+ sip_nat_mode(p));
}
}
}
/*! \brief Validate device authentication */
static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
- struct sip_request *req, int sipmethod, struct sockaddr_in *sin,
+ struct sip_request *req, int sipmethod, struct ast_sockaddr *addr,
struct sip_peer **authpeer,
enum xmittype reliable, char *calleridname, char *uri2)
{
enum check_auth_result res;
- int debug=sip_debug_test_addr(sin);
+ int debug = sip_debug_test_addr(addr);
struct sip_peer *peer;
if (sipmethod == SIP_SUBSCRIBE) {
@@ -14197,19 +14269,25 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
}
if (!peer) {
- if (debug)
- ast_verbose("No matching peer for '%s' from '%s:%d'\n",
- of, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
+ if (debug) {
+ ast_verbose("No matching peer for '%s' from '%s'\n",
+ of, ast_sockaddr_stringify(&p->recv));
+ }
return AUTH_DONT_KNOW;
}
- if (!ast_apply_ha(peer->ha, sin)) {
- ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
- unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED");
- return AUTH_ACL_FAILED;
+ if (!ast_sockaddr_is_ipv6(addr)) {
+ struct sockaddr_in sin_tmp;
+
+ ast_sockaddr_to_sin(addr, &sin_tmp);
+ if (!ast_apply_ha(peer->ha, &sin_tmp)) {
+ ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
+ unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED");
+ return AUTH_ACL_FAILED;
+ }
}
if (debug)
- ast_verbose("Found peer '%s' for '%s' from %s:%d\n",
- peer->name, of, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
+ ast_verbose("Found peer '%s' for '%s' from %s\n",
+ peer->name, of, ast_sockaddr_stringify(&p->recv));
/* XXX what about p->prefs = peer->prefs; ? */
/* Set Frame packetization */
@@ -14346,7 +14424,7 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
*/
static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_request *req,
int sipmethod, const char *uri, enum xmittype reliable,
- struct sockaddr_in *sin, struct sip_peer **authpeer)
+ struct ast_sockaddr *addr, struct sip_peer **authpeer)
{
char from[256] = { 0, };
char *dummy = NULL; /* dummy return value for parse_uri */
@@ -14392,7 +14470,7 @@ static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_requ
ast_string_field_set(p, from, of);
/* ignore all fields but name */
- if (parse_uri(of, "sip:,sips:", &of, &dummy, &domain, &dummy, NULL)) {
+ if (parse_uri(of, "sip:,sips:", &of, &dummy, &domain, NULL)) {
ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
}
@@ -14438,7 +14516,7 @@ static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_requ
}
}
- res = check_peer_ok(p, of, req, sipmethod, sin,
+ res = check_peer_ok(p, of, req, sipmethod, addr,
authpeer, reliable, calleridname, uri2);
if (res != AUTH_DONT_KNOW)
return res;
@@ -14467,9 +14545,9 @@ static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_requ
/*! \brief Find user
If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced
*/
-static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct sockaddr_in *sin)
+static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr)
{
- return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
+ return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL);
}
/*! \brief Get text out of a SIP MESSAGE packet */
@@ -14674,8 +14752,8 @@ static char *sip_show_tcp(struct ast_cli_entry *e, int cmd, struct ast_cli_args
struct sip_threadinfo *th;
struct ao2_iterator i;
-#define FORMAT2 "%-30.30s %3.6s %9.9s %6.6s\n"
-#define FORMAT "%-30.30s %-6d %-9.9s %-6.6s\n"
+#define FORMAT2 "%-47.47s %9.9s %6.6s\n"
+#define FORMAT "%-47.47s %-9.9s %-6.6s\n"
switch (cmd) {
case CLI_INIT:
@@ -14691,12 +14769,12 @@ static char *sip_show_tcp(struct ast_cli_entry *e, int cmd, struct ast_cli_args
if (a->argc != 3)
return CLI_SHOWUSAGE;
- ast_cli(a->fd, FORMAT2, "Host", "Port", "Transport", "Type");
+ ast_cli(a->fd, FORMAT2, "Address", "Transport", "Type");
i = ao2_iterator_init(threadt, 0);
while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
- ast_cli(a->fd, FORMAT, ast_inet_ntoa(th->tcptls_session->remote_address.sin_addr),
- ntohs(th->tcptls_session->remote_address.sin_port),
+ ast_cli(a->fd, FORMAT,
+ ast_sockaddr_stringify(&th->tcptls_session->remote_address),
get_transport(th->type),
(th->tcptls_session->client ? "Client" : "Server"));
ao2_t_ref(th, -1, "decrement ref from iterator");
@@ -14890,8 +14968,8 @@ static char *_sip_show_peers(int fd, int *total, struct mansession *s, const str
struct ao2_iterator i;
/* the last argument is left-aligned, so we don't need a size anyways */
-#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n"
-#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"
+#define FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n"
+#define FORMAT "%-25.25s %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"
char name[256];
int total_peers = 0;
@@ -14982,28 +15060,29 @@ static char *_sip_show_peers(int fd, int *total, struct mansession *s, const str
else if (pstatus == 0)
peers_mon_offline++;
else {
- if (peer->addr.sin_port == 0)
+ if (ast_sockaddr_isnull(&peer->addr) ||
+ !ast_sockaddr_port(&peer->addr)) {
peers_unmon_offline++;
- else
+ } else {
peers_unmon_online++;
+ }
}
snprintf(srch, sizeof(srch), FORMAT, name,
- peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
+ ast_sockaddr_isnull(&peer->addr) ? "(Unspecified)" : ast_sockaddr_stringify_addr(&peer->addr),
peer->host_dynamic ? " D " : " ", /* Dynamic or not? */
ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */
peer->ha ? " A " : " ", /* permit/deny */
- ntohs(peer->addr.sin_port), status,
+ ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), status,
realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
if (!s) {/* Normal CLI list */
ast_cli(fd, FORMAT, name,
- peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
+ ast_sockaddr_isnull(&peer->addr) ? "(Unspecified)" : ast_sockaddr_stringify_addr(&peer->addr),
peer->host_dynamic ? " D " : " ", /* Dynamic or not? */
ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */
peer->ha ? " A " : " ", /* permit/deny */
-
- ntohs(peer->addr.sin_port), status,
+ ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), status,
realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
} else { /* Manager format */
/* The names here need to be the same as other channels */
@@ -15023,8 +15102,8 @@ static char *_sip_show_peers(int fd, int *total, struct mansession *s, const str
"RealtimeDevice: %s\r\n\r\n",
idtext,
peer->name,
- peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
- ntohs(peer->addr.sin_port),
+ ast_sockaddr_isnull(&peer->addr) ? "-none-" : ast_sockaddr_stringify(&peer->addr),
+ ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr),
peer->host_dynamic ? "yes" : "no", /* Dynamic or not? */
ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no", /* NAT=yes? */
ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
@@ -15361,17 +15440,16 @@ static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli
struct sip_peer tmp;
ast_copy_string(tmp.name, name, sizeof(tmp.name));
if ((peer = ao2_t_find(peers, &tmp, OBJ_POINTER | OBJ_UNLINK, "finding to unlink from peers"))) {
- if (peer->addr.sin_addr.s_addr) {
+ if (!ast_sockaddr_isnull(&peer->addr)) {
ao2_t_unlink(peers_by_ip, peer, "unlinking peer from peers_by_ip also");
}
if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
/* put it back! */
ao2_t_link(peers, peer, "link peer into peer table");
- if (peer->addr.sin_addr.s_addr) {
+ if (!ast_sockaddr_isnull(&peer->addr)) {
ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
}
-
} else
ast_cli(a->fd, "Peer '%s' pruned.\n", name);
unref_peer(peer, "sip_prune_realtime: unref_peer: tossing temp peer ptr");
@@ -15675,8 +15753,8 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1);
ast_cli(fd, " Timer B : %d\n", peer->timer_b);
ast_cli(fd, " ToHost : %s\n", peer->tohost);
- ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
- ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
+ ast_cli(fd, " Addr->IP : %s\n", ast_sockaddr_stringify(&peer->addr));
+ ast_cli(fd, " Defaddr->IP : %s\n", ast_sockaddr_stringify(&peer->defaddr));
ast_cli(fd, " Prim.Transp. : %s\n", get_transport(peer->socket.type));
ast_cli(fd, " Allowed.Trsp : %s\n", get_transport_list(peer->transports));
if (!ast_strlen_zero(sip_cfg.regcontext))
@@ -15781,8 +15859,8 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
/* - is enumerated */
astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
astman_append(s, "ToHost: %s\r\n", peer->tohost);
- astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port));
- astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
+ astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", ast_sockaddr_stringify_addr(&peer->addr), ast_sockaddr_port(&peer->addr));
+ astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_sockaddr_stringify_addr(&peer->defaddr), ast_sockaddr_port(&peer->defaddr));
astman_append(s, "Default-Username: %s\r\n", peer->username);
if (!ast_strlen_zero(sip_cfg.regcontext))
astman_append(s, "RegExtension: %s\r\n", peer->regexten);
@@ -15983,8 +16061,8 @@ static char *sip_show_sched(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
/*! \brief Show SIP Registry (registrations with other SIP proxies */
static char *sip_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
-#define FORMAT2 "%-30.30s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n"
-#define FORMAT "%-30.30s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n"
+#define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n"
+#define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n"
char host[80];
char user[80];
char tmpdat[256];
@@ -16090,8 +16168,12 @@ static int show_chanstats_cb(void *__cur, void *__arg, int flags)
return 0; /* don't care, we scan all channels */
if (!cur->rtp) {
- if (sipdebug)
- ast_cli(fd, "%-15.15s %-11.11s (inv state: %s) -- %s\n", ast_inet_ntoa(cur->sa.sin_addr), cur->callid, invitestate2string[cur->invitestate].desc, "-- No RTP active");
+ if (sipdebug) {
+ ast_cli(fd, "%-15.15s %-11.11s (inv state: %s) -- %s\n",
+ ast_sockaddr_stringify_addr(&cur->sa), cur->callid,
+ invitestate2string[cur->invitestate].desc,
+ "-- No RTP active");
+ }
return 0; /* don't care, we scan all channels */
}
@@ -16108,7 +16190,7 @@ static int show_chanstats_cb(void *__cur, void *__arg, int flags)
}
ast_cli(fd, FORMAT,
- ast_inet_ntoa(cur->sa.sin_addr),
+ ast_sockaddr_stringify_addr(&cur->sa),
cur->callid,
durbuf,
stats.rxcount > (unsigned int) 100000 ? (unsigned int) (stats.rxcount)/(unsigned int) 1000 : stats.rxcount,
@@ -16183,22 +16265,15 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
return CLI_SHOWUSAGE;
ast_cli(a->fd, "\n\nGlobal Settings:\n");
ast_cli(a->fd, "----------------\n");
- ast_cli(a->fd, " UDP SIP Port: %d\n", ntohs(bindaddr.sin_port));
- ast_cli(a->fd, " UDP Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr));
- ast_cli(a->fd, " TCP SIP Port: ");
- if (sip_tcp_desc.local_address.sin_family == AF_INET) {
- ast_cli(a->fd, "%d\n", ntohs(sip_tcp_desc.local_address.sin_port));
- ast_cli(a->fd, " TCP Bindaddress: %s\n", ast_inet_ntoa(sip_tcp_desc.local_address.sin_addr));
- } else {
- ast_cli(a->fd, "Disabled\n");
- }
- ast_cli(a->fd, " TLS SIP Port: ");
- if (default_tls_cfg.enabled != FALSE) {
- ast_cli(a->fd, "%d\n", ntohs(sip_tls_desc.local_address.sin_port));
- ast_cli(a->fd, " TLS Bindaddress: %s\n", ast_inet_ntoa(sip_tls_desc.local_address.sin_addr));
- } else {
- ast_cli(a->fd, "Disabled\n");
- }
+ ast_cli(a->fd, " UDP Bindaddress: %s\n", ast_sockaddr_stringify(&bindaddr));
+ ast_cli(a->fd, " TCP SIP Bindaddress: %s\n",
+ sip_cfg.tcp_enabled != FALSE ?
+ ast_sockaddr_stringify(&sip_tcp_desc.local_address) :
+ "Disabled");
+ ast_cli(a->fd, " TLS SIP Bindaddress: %s\n",
+ default_tls_cfg.enabled != FALSE ?
+ ast_sockaddr_stringify(&sip_tls_desc.local_address) :
+ "Disabled");
ast_cli(a->fd, " Videosupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT)));
ast_cli(a->fd, " Textsupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT)));
ast_cli(a->fd, " Ignore SDP sess. ver.: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION)));
@@ -16263,8 +16338,8 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
/* determine if/how SIP address can be remapped */
if (localaddr == NULL)
msg = "Disabled, no localnet list";
- else if (externip.sin_addr.s_addr == 0)
- msg = "Disabled, externip is 0.0.0.0";
+ else if (ast_sockaddr_isnull(&externip))
+ msg = "Disabled";
else if (stunaddr.sin_addr.s_addr != 0)
msg = "Enabled using STUN";
else if (!ast_strlen_zero(externhost))
@@ -16273,9 +16348,9 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
msg = "Enabled using externip";
ast_cli(a->fd, " SIP address remapping: %s\n", msg);
ast_cli(a->fd, " Externhost: %s\n", S_OR(externhost, "<none>"));
- ast_cli(a->fd, " Externip: %s:%d\n", ast_inet_ntoa(externip.sin_addr), ntohs(externip.sin_port));
+ ast_cli(a->fd, " Externip: %s\n", ast_sockaddr_stringify(&externip));
ast_cli(a->fd, " Externrefresh: %d\n", externrefresh);
- ast_cli(a->fd, " Internal IP: %s:%d\n", ast_inet_ntoa(internip.sin_addr), ntohs(internip.sin_port));
+ ast_cli(a->fd, " Internal IP: %s\n", ast_sockaddr_stringify(&internip));
{
struct ast_ha *d;
const char *prefix = "Localnet:";
@@ -16437,7 +16512,7 @@ static int show_channels_cb(void *__cur, void *__arg, int flags)
{
struct sip_pvt *cur = __cur;
struct __show_chan_arg *arg = __arg;
- const struct sockaddr_in *dst = sip_real_dst(cur);
+ const struct ast_sockaddr *dst = sip_real_dst(cur);
/* XXX indentation preserved to reduce diff. Will be fixed later */
if (cur->subscribed == NONE && !arg->subscriptions) {
@@ -16445,7 +16520,7 @@ static int show_channels_cb(void *__cur, void *__arg, int flags)
const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : "";
char formatbuf[SIPBUFSIZE/2];
- ast_cli(arg->fd, FORMAT, ast_inet_ntoa(dst->sin_addr),
+ ast_cli(arg->fd, FORMAT, ast_sockaddr_stringify_addr(dst),
S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
cur->callid,
ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
@@ -16461,7 +16536,7 @@ static int show_channels_cb(void *__cur, void *__arg, int flags)
struct ast_str *mailbox_str = ast_str_alloca(512);
if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer)
peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer);
- ast_cli(arg->fd, FORMAT4, ast_inet_ntoa(dst->sin_addr),
+ ast_cli(arg->fd, FORMAT4, ast_sockaddr_stringify_addr(dst),
S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
cur->callid,
/* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
@@ -16704,11 +16779,19 @@ static char *sip_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_a
ast_cli(a->fd, " T.38 support %s\n", AST_CLI_YESNO(cur->udptl != NULL));
ast_cli(a->fd, " Video support %s\n", AST_CLI_YESNO(cur->vrtp != NULL));
ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate);
- ast_cli(a->fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
- ast_cli(a->fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
+ ast_cli(a->fd, " Theoretical Address: %s\n", ast_sockaddr_stringify(&cur->sa));
+ ast_cli(a->fd, " Received Address: %s\n", ast_sockaddr_stringify(&cur->recv));
ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer));
ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_NAT_FORCE_RPORT)));
- ast_cli(a->fd, " Audio IP: %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip.sin_addr), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" );
+ if (ast_sockaddr_isnull(&cur->redirip)) {
+ ast_cli(a->fd,
+ " Audio IP: %s (local)\n",
+ ast_sockaddr_stringify_addr(&cur->ourip));
+ } else {
+ ast_cli(a->fd,
+ " Audio IP: %s (Outside bridge)\n",
+ ast_sockaddr_stringify_addr(&cur->redirip));
+ }
ast_cli(a->fd, " Our Tag: %s\n", cur->tag);
ast_cli(a->fd, " Their Tag: %s\n", cur->theirtag);
ast_cli(a->fd, " SIP User agent: %s\n", cur->useragent);
@@ -17045,27 +17128,11 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
/*! \brief Enable SIP Debugging for a single IP */
static char *sip_do_debug_ip(int fd, const char *arg)
{
- struct hostent *hp;
- struct ast_hostent ahp;
- int port = 0;
- char *p;
-
- p = ast_strdupa(arg);
- strsep(&p, ":");
- if (p)
- port = atoi(p);
- hp = ast_gethostbyname(arg, &ahp);
- if (hp == NULL)
+ if (ast_sockaddr_resolve_first(&debugaddr, arg, 0)) {
return CLI_SHOWUSAGE;
+ }
- debugaddr.sin_family = AF_INET;
- memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
- debugaddr.sin_port = htons(port);
- if (port == 0)
- ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
- else
- ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
-
+ ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr));
sipdebug |= sip_debug_console;
return CLI_SUCCESS;
@@ -17077,14 +17144,11 @@ static char *sip_do_debug_peer(int fd, const char *arg)
struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE, 0);
if (!peer)
ast_cli(fd, "No such peer '%s'\n", arg);
- else if (peer->addr.sin_addr.s_addr == 0)
+ else if (ast_sockaddr_isnull(&peer->addr))
ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg);
else {
- debugaddr.sin_family = AF_INET;
- debugaddr.sin_addr = peer->addr.sin_addr;
- debugaddr.sin_port = peer->addr.sin_port;
- ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n",
- ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
+ ast_sockaddr_copy(&debugaddr, &peer->addr);
+ ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr));
sipdebug |= sip_debug_console;
}
if (peer)
@@ -17394,7 +17458,7 @@ static int build_reply_digest(struct sip_pvt *p, int method, char* digest, int d
else if (!ast_strlen_zero(p->uri))
ast_copy_string(uri, p->uri, sizeof(uri));
else
- snprintf(uri, sizeof(uri), "sip:%s@%s", p->username, ast_inet_ntoa(p->sa.sin_addr));
+ snprintf(uri, sizeof(uri), "sip:%s@%s", p->username, ast_sockaddr_stringify_host(&p->sa));
snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
@@ -17548,9 +17612,9 @@ static int function_sippeer(struct ast_channel *chan, const char *cmd, char *dat
return -1;
if (!strcasecmp(colname, "ip")) {
- ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
+ ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
} else if (!strcasecmp(colname, "port")) {
- snprintf(buf, len, "%d", ntohs(peer->addr.sin_port));
+ snprintf(buf, len, "%d", ast_sockaddr_port(&peer->addr));
} else if (!strcasecmp(colname, "status")) {
peer_status(peer, buf, len);
} else if (!strcasecmp(colname, "language")) {
@@ -17659,9 +17723,9 @@ static int function_sipchaninfo_read(struct ast_channel *chan, const char *cmd,
}
if (!strcasecmp(data, "peerip")) {
- ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
+ ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->sa), len);
} else if (!strcasecmp(data, "recvip")) {
- ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
+ ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->recv), len);
} else if (!strcasecmp(data, "from")) {
ast_copy_string(buf, p->from, len);
} else if (!strcasecmp(data, "uri")) {
@@ -18458,7 +18522,7 @@ static void handle_response_notify(struct sip_pvt *p, int resp, const char *rest
}
ast_string_field_set(p, theirtag, NULL);
if (ast_strlen_zero(p->authname)) {
- ast_log(LOG_WARNING, "Asked to authenticate NOTIFY to %s:%d but we have no matching peer or realm auth!\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
+ ast_log(LOG_WARNING, "Asked to authenticate NOTIFY to %s but we have no matching peer or realm auth!\n", ast_sockaddr_stringify(&p->recv));
pvt_set_needdestroy(p, "unable to authenticate NOTIFY");
}
if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_NOTIFY, 0)) {
@@ -18553,8 +18617,8 @@ static void handle_response_refer(struct sip_pvt *p, int resp, const char *rest,
case 401: /* Not www-authorized on SIP method */
case 407: /* Proxy auth */
if (ast_strlen_zero(p->authname)) {
- ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
- ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
+ ast_log(LOG_WARNING, "Asked to authenticate REFER to %s but we have no matching peer or realm auth!\n",
+ ast_sockaddr_stringify(&p->recv));
if (p->owner) {
ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
}
@@ -18985,8 +19049,8 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
if (p->options)
p->options->auth_type = resp;
if (ast_strlen_zero(p->authname)) {
- ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
- msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
+ ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n",
+ msg, ast_sockaddr_stringify(&p->recv));
pvt_set_needdestroy(p, "unable to authenticate BYE");
} else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, sipmethod, 0)) {
ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
@@ -19093,7 +19157,7 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
else if (sipmethod == SIP_REFER)
handle_response_refer(p, resp, rest, req, seqno);
else
- ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg);
+ ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_sockaddr_stringify(&p->sa), msg);
break;
case 603: /* Declined transfer */
if (sipmethod == SIP_REFER) {
@@ -19105,7 +19169,7 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
if ((resp >= 300) && (resp < 700)) {
/* Fatal response */
if ((resp != 487))
- ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
+ ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa));
if (sipmethod == SIP_INVITE)
stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
@@ -19177,7 +19241,7 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
}
}
} else
- ast_log(LOG_NOTICE, "Don't know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(p->sa.sin_addr));
+ ast_log(LOG_NOTICE, "Don't know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_sockaddr_stringify(&p->sa));
}
} else {
/* Responses to OUTGOING SIP requests on INCOMING calls
@@ -19286,7 +19350,7 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
}
if ((resp >= 300) && (resp < 700)) {
if ((resp != 487))
- ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
+ ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa));
switch(resp) {
case 415: /* Unsupported media type */
case 488: /* Not acceptable here - codec error */
@@ -19637,7 +19701,7 @@ static int handle_cc_notify(struct sip_pvt *pvt, struct sip_request *req)
}
/*! \brief Handle incoming notifications */
-static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, const char *e)
+static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int seqno, const char *e)
{
/* This is mostly a skeleton for future improvements */
/* Mostly created to return proper answers on notifications on outbound REFER's */
@@ -19867,7 +19931,7 @@ static int handle_request_options(struct sip_pvt *p, struct sip_request *req)
handle_request_do(), we unlock p->owner before the masq. By setting nounlock
we are indicating to handle_request_do() that we have already unlocked the owner.
*/
-static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *nounlock)
+static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct ast_sockaddr *addr, int *nounlock)
{
int earlyreplace = 0;
int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */
@@ -20356,7 +20420,7 @@ static int handle_request_update(struct sip_pvt *p, struct sip_request *req)
* plan but try to find the active call and masquerade
* into it
*/
-static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, const char *e, int *nounlock)
+static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct ast_sockaddr *addr, int *recount, const char *e, int *nounlock)
{
int res = 1;
int gotdest;
@@ -20382,7 +20446,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
char exten[AST_MAX_EXTENSION];
char context[AST_MAX_CONTEXT];
} pickup = {
- .exten = "",
+ .exten = "",
};
st_ref = SESSION_TIMER_REFRESHER_AUTO;
@@ -20485,17 +20549,17 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
/* We already have a pending invite. Sorry. You are on hold. */
p->glareinvite = seqno;
if (p->rtp && find_sdp(req)) {
- struct sockaddr_in sin;
- if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &sin)) {
+ struct ast_sockaddr addr;
+ if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &addr)) {
ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n");
} else {
- ast_rtp_instance_set_alt_remote_address(p->rtp, &sin);
+ ast_rtp_instance_set_alt_remote_address(p->rtp, &addr);
}
if (p->vrtp) {
- if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &sin)) {
+ if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &addr)) {
ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n");
} else {
- ast_rtp_instance_set_alt_remote_address(p->vrtp, &sin);
+ ast_rtp_instance_set_alt_remote_address(p->vrtp, &addr);
}
}
}
@@ -20700,7 +20764,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
/* Handle authentication if this is our first invite */
int cc_recall_core_id = -1;
set_pvt_allowed_methods(p, req);
- res = check_user_full(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin, &authpeer);
+ res = check_user_full(p, req, SIP_INVITE, e, XMIT_RELIABLE, addr, &authpeer);
if (res == AUTH_CHALLENGE_SENT) {
p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */
res = 0;
@@ -20728,7 +20792,10 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer");
/* If T38 is needed but not present, then make it magically appear */
if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && !p->udptl) {
- if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr))) {
+ struct sockaddr_in bindaddr_sin_tmp;
+
+ ast_sockaddr_to_sin(&bindaddr, &bindaddr_sin_tmp);
+ if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr_sin_tmp.sin_addr))) {
p->t38_maxdatagram = global_t38_maxdatagram;
set_t38_capabilities(p);
} else {
@@ -21030,7 +21097,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
/* Go and take over the target call */
if (sipdebug)
ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid);
- res = handle_invite_replaces(p, req, debug, seqno, sin, nounlock);
+ res = handle_invite_replaces(p, req, debug, seqno, addr, nounlock);
refer_locked = 0;
goto request_invite_cleanup;
}
@@ -21892,7 +21959,7 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req)
if (!ast_strlen_zero(get_header(req, "Also"))) {
ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n",
- ast_inet_ntoa(p->recv.sin_addr));
+ ast_sockaddr_stringify(&p->recv));
if (ast_strlen_zero(p->context))
ast_string_field_set(p, context, sip_cfg.default_context);
res = get_also_info(p, req);
@@ -21910,7 +21977,7 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req)
ast_queue_hangup(p->owner);
}
} else {
- ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
+ ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_sockaddr_stringify(&p->recv));
if (p->owner)
ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
}
@@ -22361,7 +22428,7 @@ static int handle_sip_publish_remove(struct sip_pvt *p, struct sip_request *req,
return res;
}
-static int handle_request_publish(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, const int seqno, const char *uri)
+static int handle_request_publish(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const int seqno, const char *uri)
{
const char *etag = get_header(req, "SIP-If-Match");
const char *event = get_header(req, "Event");
@@ -22382,7 +22449,7 @@ static int handle_request_publish(struct sip_pvt *p, struct sip_request *req, st
return -1;
}
- auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_RELIABLE, sin);
+ auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_RELIABLE, addr);
if (auth_result == AUTH_CHALLENGE_SENT) {
p->lastinvite = seqno;
return 0;
@@ -22501,7 +22568,7 @@ static int handle_cc_subscribe(struct sip_pvt *p, struct sip_request *req)
}
/*! \brief Handle incoming SUBSCRIBE request */
-static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, const char *e)
+static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int seqno, const char *e)
{
int gotdest = 0;
int res = 0;
@@ -22582,7 +22649,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
event = (char *) eventheader; /* XXX is this legal ? */
/* Handle authentication */
- res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer);
+ res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, addr, &authpeer);
/* if an authentication response was sent, we are done here */
if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */
return 0;
@@ -22782,7 +22849,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
- ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_inet_ntoa(p->sa.sin_addr));
+ ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_sockaddr_stringify(&p->sa));
transmit_response(p, "404 Not found", req);
pvt_set_needdestroy(p, "no extension for SUBSCRIBE");
return 0;
@@ -22836,7 +22903,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
}
/*! \brief Handle incoming REGISTER request */
-static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, const char *e)
+static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
{
enum check_auth_result res;
@@ -22845,7 +22912,7 @@ static int handle_request_register(struct sip_pvt *p, struct sip_request *req, s
if (sipdebug)
ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
check_via(p, req);
- if ((res = register_verify(p, sin, req, e)) < 0) {
+ if ((res = register_verify(p, addr, req, e)) < 0) {
const char *reason;
switch (res) {
@@ -22875,7 +22942,7 @@ static int handle_request_register(struct sip_pvt *p, struct sip_request *req, s
break;
}
ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
- get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
+ get_header(req, "To"), ast_sockaddr_stringify(addr),
reason);
append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
} else
@@ -22892,7 +22959,7 @@ static int handle_request_register(struct sip_pvt *p, struct sip_request *req, s
/*! \brief Handle incoming SIP requests (methods)
\note This is where all incoming requests go first */
/* called with p and p->owner locked */
-static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock)
+static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int *recount, int *nounlock)
{
/* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
relatively static */
@@ -23069,7 +23136,7 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct so
res = handle_request_options(p, req);
break;
case SIP_INVITE:
- res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock);
+ res = handle_request_invite(p, req, debug, seqno, addr, recount, e, nounlock);
break;
case SIP_REFER:
res = handle_request_refer(p, req, debug, seqno, nounlock);
@@ -23084,13 +23151,13 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct so
res = handle_request_message(p, req);
break;
case SIP_PUBLISH:
- res = handle_request_publish(p, req, sin, seqno, e);
+ res = handle_request_publish(p, req, addr, seqno, e);
break;
case SIP_SUBSCRIBE:
- res = handle_request_subscribe(p, req, sin, seqno, e);
+ res = handle_request_subscribe(p, req, addr, seqno, e);
break;
case SIP_REGISTER:
- res = handle_request_register(p, req, sin, e);
+ res = handle_request_register(p, req, addr, e);
break;
case SIP_INFO:
if (req->debug)
@@ -23101,7 +23168,7 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct so
transmit_response(p, "200 OK", req);
break;
case SIP_NOTIFY:
- res = handle_request_notify(p, req, sin, seqno, e);
+ res = handle_request_notify(p, req, addr, seqno, e);
break;
case SIP_UPDATE:
res = handle_request_update(p, req);
@@ -23134,7 +23201,7 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct so
default:
transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n",
- cmd, ast_inet_ntoa(p->sa.sin_addr));
+ cmd, ast_sockaddr_stringify(&p->sa));
/* If this is some new method, and we don't have a call, destroy it now */
if (!p->initreq.headers) {
pvt_set_needdestroy(p, "unimplemented method");
@@ -23241,13 +23308,12 @@ static int queue_request(struct sip_pvt *p, const struct sip_request *req)
static int sipsock_read(int *id, int fd, short events, void *ignore)
{
struct sip_request req;
- struct sockaddr_in sin = { 0, };
+ struct ast_sockaddr addr;
int res;
- socklen_t len = sizeof(sin);
static char readbuf[65535];
memset(&req, 0, sizeof(req));
- res = recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, (struct sockaddr *)&sin, &len);
+ res = ast_recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, &addr);
if (res < 0) {
#if !defined(__FreeBSD__)
if (errno == EAGAIN)
@@ -23273,9 +23339,9 @@ static int sipsock_read(int *id, int fd, short events, void *ignore)
req.socket.fd = sipsock;
set_socket_transport(&req.socket, SIP_TRANSPORT_UDP);
req.socket.tcptls_session = NULL;
- req.socket.port = bindaddr.sin_port;
+ req.socket.port = htons(ast_sockaddr_port(&bindaddr));
- handle_request_do(&req, &sin);
+ handle_request_do(&req, &addr);
deinit_req(&req);
return 1;
@@ -23285,21 +23351,20 @@ static int sipsock_read(int *id, int fd, short events, void *ignore)
This is used for all transports (udp, tcp and tcp/tls)
*/
-static int handle_request_do(struct sip_request *req, struct sockaddr_in *sin)
+static int handle_request_do(struct sip_request *req, struct ast_sockaddr *addr)
{
struct sip_pvt *p;
int recount = 0;
int nounlock = 0;
int lockretry;
- if (sip_debug_test_addr(sin)) /* Set the debug flag early on packet level */
+ if (sip_debug_test_addr(addr)) /* Set the debug flag early on packet level */
req->debug = 1;
if (sip_cfg.pedanticsipchecking)
req->len = lws2sws(req->data->str, req->len); /* Fix multiline headers */
if (req->debug) {
- ast_verbose("\n<--- SIP read from %s:%s:%d --->\n%s\n<------------->\n",
- get_transport(req->socket.type), ast_inet_ntoa(sin->sin_addr),
- ntohs(sin->sin_port), req->data->str);
+ ast_verbose("\n<--- SIP read from %s:%s --->\n%s\n<------------->\n",
+ get_transport(req->socket.type), ast_sockaddr_stringify(addr), req->data->str);
}
if (parse_request(req) == -1) { /* Bad packet, can't parse */
@@ -23321,7 +23386,7 @@ static int handle_request_do(struct sip_request *req, struct sockaddr_in *sin)
ast_mutex_lock(&netlock);
/* Find the active SIP dialog or create a new one */
- p = find_call(req, sin, req->method); /* returns p locked */
+ p = find_call(req, addr, req->method); /* returns p locked */
if (p == NULL) {
ast_debug(1, "Invalid SIP message - rejected , no callid, len %d\n", req->len);
ast_mutex_unlock(&netlock);
@@ -23343,7 +23408,7 @@ static int handle_request_do(struct sip_request *req, struct sockaddr_in *sin)
usleep(1);
}
}
- p->recv = *sin;
+ ast_sockaddr_copy(&p->recv, addr);
if (p->do_history) /* This is a request or response, note what it was for */
append_history(p, "Rx", "%s / %s / %s", req->data->str, get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2));
@@ -23378,7 +23443,7 @@ static int handle_request_do(struct sip_request *req, struct sockaddr_in *sin)
process_request_queue(p, &recount, &nounlock);
}
- if (handle_incoming(p, req, sin, &recount, &nounlock) == -1) {
+ if (handle_incoming(p, req, addr, &recount, &nounlock) == -1) {
/* Request failed */
ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
}
@@ -23411,9 +23476,9 @@ static int sip_standard_port(enum sip_transport type, int port)
static int threadinfo_locate_cb(void *obj, void *arg, int flags)
{
struct sip_threadinfo *th = obj;
- struct sockaddr_in *s = arg;
+ struct ast_sockaddr *s = arg;
- if (!inaddrcmp(&th->tcptls_session->remote_address, s)) {
+ if (!ast_sockaddr_cmp(s, &th->tcptls_session->remote_address)) {
return CMP_MATCH | CMP_STOP;
}
@@ -23425,7 +23490,7 @@ static int threadinfo_locate_cb(void *obj, void *arg, int flags)
*
* \note This function returns an astobj2 reference
*/
-static struct ast_tcptls_session_instance *sip_tcp_locate(struct sockaddr_in *s)
+static struct ast_tcptls_session_instance *sip_tcp_locate(struct ast_sockaddr *s)
{
struct sip_threadinfo *th;
struct ast_tcptls_session_instance *tcptls_instance = NULL;
@@ -23438,6 +23503,20 @@ static struct ast_tcptls_session_instance *sip_tcp_locate(struct sockaddr_in *s)
return tcptls_instance;
}
+/*!
+ * \brief Helper for dns resolution to filter by address family.
+ *
+ * \note return 0 if addr is [::] else it returns addr's family.
+ */
+int get_address_family_filter(const struct ast_sockaddr *addr)
+{
+ if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) {
+ return 0;
+ }
+
+ return addr->ss.ss_family;
+}
+
/*! \todo Get socket for dialog, prepare if needed, and return file handle */
static int sip_prepare_socket(struct sip_pvt *p)
{
@@ -23445,11 +23524,8 @@ static int sip_prepare_socket(struct sip_pvt *p)
static const char name[] = "SIP socket";
struct sip_threadinfo *th = NULL;
struct ast_tcptls_session_instance *tcptls_session;
- struct ast_tcptls_session_args tmp_ca = {
- .name = name,
- .accept_fd = -1,
- };
struct ast_tcptls_session_args *ca;
+ struct ast_sockaddr sa_tmp;
/* check to see if a socket is already active */
if ((s->fd != -1) && (s->type == SIP_TRANSPORT_UDP)) {
@@ -23483,8 +23559,8 @@ static int sip_prepare_socket(struct sip_pvt *p)
*/
/* 1. check for existing threads */
- tmp_ca.remote_address = *(sip_real_dst(p));
- if ((tcptls_session = sip_tcp_locate(&tmp_ca.remote_address))) {
+ ast_sockaddr_copy(&sa_tmp, sip_real_dst(p));
+ if ((tcptls_session = sip_tcp_locate(&sa_tmp))) {
s->fd = tcptls_session->fd;
if (s->tcptls_session) {
ao2_ref(s->tcptls_session, -1);
@@ -23504,7 +23580,7 @@ static int sip_prepare_socket(struct sip_pvt *p)
goto create_tcptls_session_fail;
}
ca->accept_fd = -1;
- ca->remote_address = *(sip_real_dst(p));
+ ast_sockaddr_copy(&ca->remote_address,sip_real_dst(p));
/* if type is TLS, we need to create a tls cfg for this session arg */
if (s->type == SIP_TRANSPORT_TLS) {
if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) {
@@ -23606,7 +23682,7 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, const struct ast_event *e
return 0;
/* Do we have an IP address? If not, skip this peer */
- if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr)
+ if (ast_sockaddr_isnull(&peer->addr) || ast_sockaddr_isnull(&peer->defaddr))
return 0;
if (event) {
@@ -23642,7 +23718,7 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, const struct ast_event *e
return 0;
}
/* Recalculate our side, and recalculate Call ID */
- ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
+ ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
build_via(p);
ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
build_callid_pvt(p);
@@ -23672,7 +23748,7 @@ static void check_rtp_timeout(struct sip_pvt *dialog, time_t t)
return;
/* If the call is not in UP state or redirected outside Asterisk, no need to check timers */
- if (dialog->owner->_state != AST_STATE_UP || dialog->redirip.sin_addr.s_addr)
+ if (dialog->owner->_state != AST_STATE_UP || !ast_sockaddr_isnull(&dialog->redirip))
return;
/* If the call is involved in a T38 fax session do not check RTP timeout */
@@ -24179,7 +24255,7 @@ static int sip_poke_peer(struct sip_peer *peer, int force)
struct sip_pvt *p;
int xmitres = 0;
- if ((!peer->maxms && !force) || !peer->addr.sin_addr.s_addr) {
+ if ((!peer->maxms && !force) || ast_sockaddr_isnull(&peer->addr)) {
/* IF we have no IP, or this isn't to be monitored, return
immediately after clearing things out */
AST_SCHED_DEL_UNREF(sched, peer->pokeexpire,
@@ -24218,10 +24294,10 @@ static int sip_poke_peer(struct sip_peer *peer, int force)
if (!ast_strlen_zero(peer->tohost))
ast_string_field_set(p, tohost, peer->tohost);
else
- ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
+ ast_string_field_set(p, tohost, ast_sockaddr_stringify_host(&peer->addr));
/* Recalculate our side, and recalculate Call ID */
- ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
+ ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
build_via(p);
ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
build_callid_pvt(p);
@@ -24309,7 +24385,7 @@ static int sip_devicestate(void *data)
* hosts out of memory.
*/
if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE, 0))) {
- if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
+ if (!(ast_sockaddr_isnull(&p->addr) && ast_sockaddr_isnull(&p->defaddr))) {
/* we have an address for the peer */
/* Check status in this order
@@ -24380,7 +24456,7 @@ static struct ast_channel *sip_request_call(const char *type, format_t format, c
char dialstring[256];
char *remote_address;
enum sip_transport transport = 0;
- struct sockaddr_in remote_address_sin = { .sin_family = AF_INET };
+ struct ast_sockaddr remote_address_sa = { {0,} };
format_t oldformat = format;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(peerorhost);
@@ -24482,25 +24558,15 @@ static struct ast_channel *sip_request_call(const char *type, format_t format, c
}
if (!ast_strlen_zero(remote_address)) {
- struct hostent *hp;
- struct ast_hostent ahp;
- char *port;
- unsigned short port_num = transport & SIP_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
-
- port = strchr(remote_address, ':');
- if (port) {
- *port++ = '\0';
- if (sscanf(port, "%hu", &port_num) != 1) {
- ast_log(LOG_WARNING, "Invalid port number provided in remote address. Using %hu\n", port_num);
- }
- }
-
- hp = ast_gethostbyname(remote_address, &ahp);
- if (!hp) {
+ if (ast_sockaddr_resolve_first(&remote_address_sa, remote_address, 0)) {
ast_log(LOG_WARNING, "Unable to find IP address for host %s. We will not use this remote IP address\n", remote_address);
} else {
- memcpy(&remote_address_sin.sin_addr, hp->h_addr, sizeof(remote_address_sin.sin_addr));
- remote_address_sin.sin_port = htons(port_num);
+ if (!ast_sockaddr_port(&remote_address_sa)) {
+ ast_sockaddr_set_port(&remote_address_sa,
+ transport & SIP_TRANSPORT_TLS ?
+ STANDARD_TLS_PORT :
+ STANDARD_SIP_PORT);
+ }
}
}
@@ -24511,7 +24577,7 @@ static struct ast_channel *sip_request_call(const char *type, format_t format, c
ext = extension (user part of URI)
dnid = destination of the call (applies to the To: header)
*/
- if (create_addr(p, host, NULL, 1, &remote_address_sin)) {
+ if (create_addr(p, host, NULL, 1, &remote_address_sa)) {
*cause = AST_CAUSE_UNREGISTERED;
ast_debug(3, "Cant create SIP call - target device not registered\n");
dialog_unlink_all(p, TRUE, TRUE);
@@ -24522,7 +24588,7 @@ static struct ast_channel *sip_request_call(const char *type, format_t format, c
if (ast_strlen_zero(p->peername) && ext)
ast_string_field_set(p, peername, ext);
/* Recalculate our side, and recalculate Call ID */
- ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
+ ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
build_via(p);
ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
build_callid_pvt(p);
@@ -24961,7 +25027,6 @@ static void set_peer_defaults(struct sip_peer *peer)
*/
peer->expire = -1;
peer->pokeexpire = -1;
- peer->addr.sin_port = htons(STANDARD_SIP_PORT);
set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP);
}
peer->type = SIP_TYPE_PEER;
@@ -24974,8 +25039,8 @@ static void set_peer_defaults(struct sip_peer *peer)
ast_string_field_set(peer, mohinterpret, default_mohinterpret);
ast_string_field_set(peer, mohsuggest, default_mohsuggest);
ast_string_field_set(peer, engine, default_engine);
- peer->addr.sin_family = AF_INET;
- peer->defaddr.sin_family = AF_INET;
+ ast_sockaddr_setnull(&peer->addr);
+ ast_sockaddr_setnull(&peer->defaddr);
peer->capability = sip_cfg.capability;
peer->maxcallbitrate = default_maxcallbitrate;
peer->rtptimeout = global_rtptimeout;
@@ -25262,41 +25327,58 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
} else if (!strcasecmp(v->name, "fromuser")) {
ast_string_field_set(peer, fromuser, v->value);
} else if (!strcasecmp(v->name, "outboundproxy")) {
- char *port, *next, *force, *proxyname;
- int forceopt = FALSE;
- /* Set peer channel variable */
- next = proxyname = ast_strdupa(v->value);
- if ((port = strchr(proxyname, ':'))) {
- *port++ = '\0';
- next = port;
+ char *tok, *proxyname;
+
+ if (ast_strlen_zero(v->value)) {
+ ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno);
+ continue;
}
- if ((force = strchr(next, ','))) {
- *force++ = '\0';
- forceopt = strcmp(force, "force");
+
+ peer->outboundproxy =
+ ao2_alloc(sizeof(*peer->outboundproxy), NULL);
+
+ tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ","));
+
+ sip_parse_host(tok, v->lineno, &proxyname,
+ &peer->outboundproxy->port,
+ &peer->outboundproxy->transport);
+
+ tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ","));
+
+ if ((tok = strtok(NULL, ","))) {
+ peer->outboundproxy->force = !strncasecmp(ast_skip_blanks(tok), "force", 5);
+ } else {
+ peer->outboundproxy->force = FALSE;
+ }
+
+ if (ast_strlen_zero(proxyname)) {
+ ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno);
+ sip_cfg.outboundproxy.name[0] = '\0';
+ continue;
}
- /* Allocate proxy object */
- peer->outboundproxy = proxy_allocate(proxyname, port, forceopt);
+
+ ast_copy_string(peer->outboundproxy->name, proxyname, sizeof(peer->outboundproxy->name));
+
+ proxy_update(peer->outboundproxy);
} else if (!strcasecmp(v->name, "host")) {
if (!strcasecmp(v->value, "dynamic")) {
/* They'll register with us */
if (!found || !peer->host_dynamic) {
/* Initialize stuff if this is a new peer, or if it used to
* not be dynamic before the reload. */
- memset(&peer->addr.sin_addr, 0, 4);
- peer->addr.sin_port = 0;
+ ast_sockaddr_setnull(&peer->addr);
}
peer->host_dynamic = TRUE;
} else {
/* Non-dynamic. Make sure we become that way if we're not */
AST_SCHED_DEL_UNREF(sched, peer->expire,
unref_peer(peer, "removing register expire ref"));
- /* the port will either be set to a default value or a config specified value once all option parsing is complete */
- peer->addr.sin_port = 0;
peer->host_dynamic = FALSE;
srvlookup = v->value;
if (global_dynamic_exclude_static) {
int err = 0;
- sip_cfg.contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), sip_cfg.contact_ha, &err);
+ sip_cfg.contact_ha = ast_append_ha("deny", ast_sockaddr_stringify(&peer->addr),
+ sip_cfg.contact_ha, &err);
if (err) {
ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
}
@@ -25504,7 +25586,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
if (realtime && !strcasecmp(v->name, "lastms")) {
sscanf(v->value, "%30d", &peer->lastms);
} else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
- inet_aton(v->value, &(peer->addr.sin_addr));
+ ast_sockaddr_parse(&peer->addr, v->value, PARSE_PORT_FORBID);
} else if (realtime && !strcasecmp(v->name, "fullcontact")) {
if (alt_fullcontact && !alt) {
/* Reset, because the alternate also has a fullcontact and we
@@ -25605,12 +25687,6 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
set_socket_transport(&peer->socket, peer->default_outbound_transport);
}
- if (port && !realtime && peer->host_dynamic) {
- peer->defaddr.sin_port = htons(port);
- } else if (port) {
- peer->addr.sin_port = htons(port);
- }
-
if (ast_str_strlen(fullcontact)) {
ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact));
peer->rt_fromcontact = TRUE;
@@ -25622,7 +25698,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
* specified, use that address instead. */
/* XXX May need to revisit the final argument; does the realtime DB store whether
* the original contact was over TLS or not? XXX */
- if (!ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT) || !peer->addr.sin_addr.s_addr) {
+ if (!ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT) || ast_sockaddr_isnull(&peer->addr)) {
__set_address_from_contact(fullcontact->str, &peer->addr, 0);
}
}
@@ -25639,20 +25715,32 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
snprintf(transport, sizeof(transport), "_sip._%s", get_transport(peer->socket.type));
+ peer->addr.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL)) {
ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
unref_peer(peer, "getting rid of a peer pointer");
return NULL;
}
- ast_string_field_set(peer, tohost, srvlookup);
+ ast_string_field_set(peer, tohost, peer->dnsmgr ? srvlookup :
+ ast_sockaddr_stringify_host(&peer->addr));
+ }
+
+ if (port && !realtime && peer->host_dynamic) {
+ ast_sockaddr_set_port(&peer->defaddr, port);
+ } else if (port) {
+ ast_sockaddr_set_port(&peer->addr, port);
}
- if (!peer->addr.sin_port) {
- peer->addr.sin_port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
+ if (ast_sockaddr_port(&peer->addr) == 0) {
+ ast_sockaddr_set_port(&peer->addr,
+ (peer->socket.type & SIP_TRANSPORT_TLS) ?
+ STANDARD_TLS_PORT : STANDARD_SIP_PORT);
}
- if (!peer->defaddr.sin_port) {
- peer->defaddr.sin_port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
+ if (ast_sockaddr_port(&peer->defaddr) == 0) {
+ ast_sockaddr_set_port(&peer->defaddr,
+ (peer->socket.type & SIP_TRANSPORT_TLS) ?
+ STANDARD_TLS_PORT : STANDARD_SIP_PORT);
}
if (!peer->socket.port) {
peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
@@ -25735,12 +25823,14 @@ static int reload_config(enum channelreloadreason reason)
struct ast_flags dummy[2];
struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED };
int auto_sip_domains = FALSE;
- struct sockaddr_in old_bindaddr = bindaddr;
+ struct ast_sockaddr old_bindaddr = bindaddr;
int registry_count = 0, peer_count = 0, timerb_set = 0, timert1_set = 0;
time_t run_start, run_end;
-
+ struct sockaddr_in externip_sin;
+ int bindport = 0;
+
run_start = time(0);
- ast_unload_realtime("sipregs");
+ ast_unload_realtime("sipregs");
ast_unload_realtime("sippeers");
cfg = ast_config_load(config, config_flags);
@@ -25775,18 +25865,11 @@ static int reload_config(enum channelreloadreason reason)
}
}
- /* Initialize tcp sockets */
- memset(&sip_tcp_desc.local_address, 0, sizeof(sip_tcp_desc.local_address));
- memset(&sip_tls_desc.local_address, 0, sizeof(sip_tls_desc.local_address));
-
ast_free_ha(sip_cfg.contact_ha);
sip_cfg.contact_ha = NULL;
default_tls_cfg.enabled = FALSE; /* Default: Disable TLS */
- sip_tcp_desc.local_address.sin_port = htons(STANDARD_SIP_PORT);
- sip_tls_desc.local_address.sin_port = htons(STANDARD_TLS_PORT);
-
if (reason != CHANNEL_MODULE_LOAD) {
ast_debug(4, "--------------- SIP reload started\n");
@@ -25845,7 +25928,7 @@ static int reload_config(enum channelreloadreason reason)
ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
/* Reset IP addresses */
- memset(&bindaddr, 0, sizeof(bindaddr));
+ ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
memset(&stunaddr, 0, sizeof(stunaddr));
memset(&internip, 0, sizeof(internip));
@@ -25856,16 +25939,13 @@ static int reload_config(enum channelreloadreason reason)
memset(&media_address, 0, sizeof(media_address));
memset(&default_prefs, 0 , sizeof(default_prefs));
memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy));
- sip_cfg.outboundproxy.ip.sin_port = htons(STANDARD_SIP_PORT);
- sip_cfg.outboundproxy.ip.sin_family = AF_INET; /*!< Type of address: IPv4 */
sip_cfg.outboundproxy.force = FALSE; /*!< Don't force proxy usage, use route: headers */
default_transports = 0; /*!< Reset default transport to zero here, default value later on */
default_primary_transport = 0; /*!< Reset default primary transport to zero here, default value later on */
ourport_tcp = STANDARD_SIP_PORT;
ourport_tls = STANDARD_TLS_PORT;
- externtcpport = 0;
- externtlsport = 0;
- bindaddr.sin_port = htons(STANDARD_SIP_PORT);
+ externtcpport = STANDARD_SIP_PORT;
+ externtlsport = STANDARD_TLS_PORT;
sip_cfg.srvlookup = DEFAULT_SRVLOOKUP;
global_tos_sip = DEFAULT_TOS_SIP;
global_tos_audio = DEFAULT_TOS_AUDIO;
@@ -25920,6 +26000,7 @@ static int reload_config(enum channelreloadreason reason)
ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for all devices: TRUE */
sip_cfg.peer_rtupdate = TRUE;
global_dynamic_exclude_static = 0; /* Exclude static peers */
+ sip_cfg.tcp_enabled = FALSE;
/* Session-Timers */
global_st_mode = SESSION_TIMER_MODE_ACCEPT;
@@ -26056,14 +26137,18 @@ static int reload_config(enum channelreloadreason reason)
}
}
} else if (!strcasecmp(v->name, "tcpenable")) {
- sip_tcp_desc.local_address.sin_family = ast_false(v->value) ? 0 : AF_INET;
- ast_debug(2, "Enabling TCP socket for listening\n");
+ if (!ast_false(v->value)) {
+ ast_debug(2, "Enabling TCP socket for listening\n");
+ sip_cfg.tcp_enabled = TRUE;
+ }
} else if (!strcasecmp(v->name, "tcpbindaddr")) {
- int family = sip_tcp_desc.local_address.sin_family;
- if (ast_parse_arg(v->value, PARSE_INADDR, &sip_tcp_desc.local_address))
- ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", v->name, v->value, v->lineno, config);
- sip_tcp_desc.local_address.sin_family = family;
- ast_debug(2, "Setting TCP socket address to %s\n", v->value);
+ if (ast_parse_arg(v->value, PARSE_ADDR,
+ &sip_tcp_desc.local_address)) {
+ ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
+ v->name, v->value, v->lineno, config);
+ }
+ ast_debug(2, "Setting TCP socket address to %s\n",
+ ast_sockaddr_stringify(&sip_tcp_desc.local_address));
} else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) {
global_dynamic_exclude_static = ast_true(v->value);
} else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
@@ -26155,7 +26240,6 @@ static int reload_config(enum channelreloadreason reason)
default_fromdomainport = STANDARD_SIP_PORT;
}
} else if (!strcasecmp(v->name, "outboundproxy")) {
- int portnum;
char *tok, *proxyname;
if (ast_strlen_zero(v->value)) {
@@ -26165,10 +26249,10 @@ static int reload_config(enum channelreloadreason reason)
tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ","));
- sip_parse_host(tok, v->lineno, &proxyname, &portnum, &sip_cfg.outboundproxy.transport);
+ sip_parse_host(tok, v->lineno, &proxyname,
+ &sip_cfg.outboundproxy.port,
+ &sip_cfg.outboundproxy.transport);
- sip_cfg.outboundproxy.ip.sin_port = htons(portnum);
-
if ((tok = strtok(NULL, ","))) {
sip_cfg.outboundproxy.force = !strncasecmp(ast_skip_blanks(tok), "force", 5);
} else {
@@ -26227,8 +26311,9 @@ static int reload_config(enum channelreloadreason reason)
ast_log(LOG_WARNING, "Invalid STUN server address: %s\n", v->value);
externexpire = time(NULL);
} else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) {
- if (ast_parse_arg(v->value, PARSE_INADDR, &bindaddr))
+ if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
+ }
} else if (!strcasecmp(v->name, "localnet")) {
struct ast_ha *na;
int ha_error = 0;
@@ -26240,23 +26325,21 @@ static int reload_config(enum channelreloadreason reason)
if (ha_error)
ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value);
} else if (!strcasecmp(v->name, "media_address")) {
- if (ast_parse_arg(v->value, PARSE_INADDR, &media_address))
+ if (ast_parse_arg(v->value, PARSE_ADDR, &media_address))
ast_log(LOG_WARNING, "Invalid address for media_address keyword: %s\n", v->value);
} else if (!strcasecmp(v->name, "externip")) {
- if (ast_parse_arg(v->value, PARSE_INADDR, &externip))
- ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
+ if (ast_parse_arg(v->value, PARSE_ADDR, &externip)) {
+ ast_log(LOG_WARNING,
+ "Invalid address for externip keyword: %s\n",
+ v->value);
+ }
externexpire = 0;
- /* If no port was specified use the value of bindport */
- if (!externip.sin_port)
- externip.sin_port = bindaddr.sin_port;
} else if (!strcasecmp(v->name, "externhost")) {
ast_copy_string(externhost, v->value, sizeof(externhost));
- if (ast_parse_arg(externhost, PARSE_INADDR, &externip))
+ if (ast_sockaddr_resolve_first(&externip, externhost, 0)) {
ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
+ }
externexpire = time(NULL);
- /* If no port was specified use the value of bindport */
- if (!externip.sin_port)
- externip.sin_port = bindaddr.sin_port;
} else if (!strcasecmp(v->name, "externrefresh")) {
if (sscanf(v->value, "%30d", &externrefresh) != 1) {
ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
@@ -26264,13 +26347,12 @@ static int reload_config(enum channelreloadreason reason)
}
} else if (!strcasecmp(v->name, "externtcpport")) {
if (!(externtcpport = port_str2int(v->value, 0))) {
- ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
- externtcpport = ntohs(sip_tcp_desc.local_address.sin_port);
+ ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
+ externtcpport = 0;
}
} else if (!strcasecmp(v->name, "externtlsport")) {
- if (!(externtlsport = port_str2int(v->value, 0))) {
+ if (!(externtlsport = port_str2int(v->value, STANDARD_TLS_PORT))) {
ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
- externtlsport = ntohs(sip_tls_desc.local_address.sin_port);
}
} else if (!strcasecmp(v->name, "allow")) {
int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE);
@@ -26331,12 +26413,8 @@ static int reload_config(enum channelreloadreason reason)
if (ast_str2cos(v->value, &global_cos_text))
ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno);
} else if (!strcasecmp(v->name, "bindport")) {
- int i;
- if (sscanf(v->value, "%5d", &i) == 1) {
- bindaddr.sin_port = htons(i);
- } else {
+ if (sscanf(v->value, "%5d", &bindport) != 1)
ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
- }
} else if (!strcasecmp(v->name, "qualify")) {
if (!strcasecmp(v->value, "no")) {
default_qualify = 0;
@@ -26449,13 +26527,6 @@ static int reload_config(enum channelreloadreason reason)
default_transports = default_primary_transport = SIP_TRANSPORT_UDP;
}
- /* if not configured, set the defaults for externtcpport and externtlsport */
- if (!externtcpport) {
- externtcpport = ntohs(externip.sin_port); /* for consistency, default to the externip port */
- }
- if (!externtlsport) {
- externtlsport = STANDARD_TLS_PORT;
- }
/* Build list of authentication to various SIP realms, i.e. service providers */
for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
/* Format for authentication is auth = username:password@realm */
@@ -26482,7 +26553,7 @@ static int reload_config(enum channelreloadreason reason)
/* user.conf entries are always of type friend */
peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
ao2_t_link(peers, peer, "link peer into peer table");
- if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
+ if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) {
ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
}
@@ -26552,7 +26623,7 @@ static int reload_config(enum channelreloadreason reason)
peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0);
if (peer) {
ao2_t_link(peers, peer, "link peer into peers table");
- if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
+ if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) {
ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
}
unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left.");
@@ -26560,22 +26631,34 @@ static int reload_config(enum channelreloadreason reason)
}
}
}
-
+
+ if (bindport) {
+ if (ast_sockaddr_port(&bindaddr)) {
+ ast_log(LOG_WARNING, "bindport is also specified in bindaddr. "
+ "Using %d.\n", bindport);
+ }
+ ast_sockaddr_set_port(&bindaddr, bindport);
+ }
+
+ if (!ast_sockaddr_port(&bindaddr)) {
+ ast_sockaddr_set_port(&bindaddr, STANDARD_SIP_PORT);
+ }
+
/* Set UDP address and open socket */
- bindaddr.sin_family = AF_INET;
- internip = bindaddr;
- if (ast_find_ourip(&internip.sin_addr, bindaddr)) {
+ ast_sockaddr_copy(&internip, &bindaddr);
+ if (ast_find_ourip(&internip, &bindaddr)) {
ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
ast_config_destroy(cfg);
return 0;
}
ast_mutex_lock(&netlock);
- if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
+ if ((sipsock > -1) && (ast_sockaddr_cmp(&old_bindaddr, &bindaddr))) {
close(sipsock);
sipsock = -1;
}
if (sipsock < 0) {
- sipsock = socket(AF_INET, SOCK_DGRAM, 0);
+ sipsock = socket(ast_sockaddr_is_ipv6(&bindaddr) ?
+ AF_INET6 : AF_INET, SOCK_DGRAM, 0);
if (sipsock < 0) {
ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
ast_config_destroy(cfg);
@@ -26590,35 +26673,43 @@ static int reload_config(enum channelreloadreason reason)
ast_enable_packet_fragmentation(sipsock);
- if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
- ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
- ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
- strerror(errno));
+ if (ast_bind(sipsock, &bindaddr) < 0) {
+ ast_log(LOG_WARNING, "Failed to bind to %s: %s\n",
+ ast_sockaddr_stringify(&bindaddr), strerror(errno));
close(sipsock);
sipsock = -1;
} else {
- ast_verb(2, "SIP Listening on %s:%d\n",
- ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
- ast_netsock_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP");
+ ast_verb(2, "SIP Listening on %s\n", ast_sockaddr_stringify(&bindaddr));
+ ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP");
}
}
}
if (stunaddr.sin_addr.s_addr != 0) {
ast_debug(1, "stun to %s:%d\n",
ast_inet_ntoa(stunaddr.sin_addr) , ntohs(stunaddr.sin_port));
+ ast_sockaddr_to_sin(&externip, &externip_sin);
ast_stun_request(sipsock, &stunaddr,
- NULL, &externip);
- ast_debug(1, "STUN sees us at %s:%d\n",
- ast_inet_ntoa(externip.sin_addr) , ntohs(externip.sin_port));
+ NULL, &externip_sin);
+ ast_debug(1, "STUN sees us at %s\n",
+ ast_sockaddr_stringify(&externip));
}
ast_mutex_unlock(&netlock);
/* Start TCP server */
+ if (sip_cfg.tcp_enabled) {
+ if (ast_sockaddr_isnull(&sip_tcp_desc.local_address)) {
+ ast_sockaddr_copy(&sip_tcp_desc.local_address, &bindaddr);
+ }
+ if (!ast_sockaddr_port(&sip_tcp_desc.local_address)) {
+ ast_sockaddr_set_port(&sip_tcp_desc.local_address, STANDARD_SIP_PORT);
+ }
+ } else {
+ ast_sockaddr_setnull(&sip_tcp_desc.local_address);
+ }
ast_tcptls_server_start(&sip_tcp_desc);
- if (sip_tcp_desc.accept_fd == -1 && sip_tcp_desc.local_address.sin_family == AF_INET) {
+ if (sip_cfg.tcp_enabled && sip_tcp_desc.accept_fd == -1) {
/* TCP server start failed. Tell the admin */
ast_log(LOG_ERROR, "SIP TCP Server start failed. Not listening on TCP socket.\n");
- sip_tcp_desc.local_address.sin_family = 0;
} else {
ast_debug(2, "SIP TCP server started\n");
}
@@ -26627,6 +26718,15 @@ static int reload_config(enum channelreloadreason reason)
memcpy(sip_tls_desc.tls_cfg, &default_tls_cfg, sizeof(default_tls_cfg));
if (ast_ssl_setup(sip_tls_desc.tls_cfg)) {
+ if (ast_sockaddr_isnull(&sip_tls_desc.local_address)) {
+ ast_sockaddr_copy(&sip_tls_desc.local_address, &bindaddr);
+ ast_sockaddr_set_port(&sip_tls_desc.local_address,
+ STANDARD_TLS_PORT);
+ }
+ if (!ast_sockaddr_port(&sip_tls_desc.local_address)) {
+ ast_sockaddr_set_port(&sip_tls_desc.local_address,
+ STANDARD_TLS_PORT);
+ }
ast_tcptls_server_start(&sip_tls_desc);
if (default_tls_cfg.enabled && sip_tls_desc.accept_fd == -1) {
ast_log(LOG_ERROR, "TLS Server start failed. Not listening on TLS socket.\n");
@@ -26647,26 +26747,36 @@ static int reload_config(enum channelreloadreason reason)
char temp[MAXHOSTNAMELEN];
/* First our default IP address */
- if (bindaddr.sin_addr.s_addr) {
- add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL);
- } else if (internip.sin_addr.s_addr) {
+ if (!ast_sockaddr_isnull(&bindaddr)) {
+ add_sip_domain(ast_sockaddr_stringify(&bindaddr), SIP_DOMAIN_AUTO, NULL);
+ } else if (!ast_sockaddr_isnull(&internip)) {
/* Our internal IP address, if configured */
- add_sip_domain(ast_inet_ntoa(internip.sin_addr), SIP_DOMAIN_AUTO, NULL);
+ add_sip_domain(ast_sockaddr_stringify(&internip), SIP_DOMAIN_AUTO, NULL);
} else {
ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
}
/* If TCP is running on a different IP than UDP, then add it too */
- if (sip_tcp_desc.local_address.sin_addr.s_addr && !inaddrcmp(&bindaddr, &sip_tcp_desc.local_address))
- add_sip_domain(ast_inet_ntoa(sip_tcp_desc.local_address.sin_addr), SIP_DOMAIN_AUTO, NULL);
+ if (!ast_sockaddr_isnull(&sip_tcp_desc.local_address) &&
+ !ast_sockaddr_cmp(&bindaddr, &sip_tcp_desc.local_address)) {
+ add_sip_domain(ast_sockaddr_stringify(&sip_tcp_desc.local_address),
+ SIP_DOMAIN_AUTO, NULL);
+ }
- /* If TLS is running on a differen IP than UDP and TCP, then add that too */
- if (sip_tls_desc.local_address.sin_addr.s_addr && !inaddrcmp(&bindaddr, &sip_tls_desc.local_address) && inaddrcmp(&sip_tcp_desc.local_address, &sip_tls_desc.local_address))
- add_sip_domain(ast_inet_ntoa(sip_tls_desc.local_address.sin_addr), SIP_DOMAIN_AUTO, NULL);
+ /* If TLS is running on a different IP than UDP and TCP, then add that too */
+ if (!ast_sockaddr_isnull(&sip_tls_desc.local_address) &&
+ !ast_sockaddr_cmp(&bindaddr, &sip_tls_desc.local_address) &&
+ !ast_sockaddr_cmp(&sip_tcp_desc.local_address,
+ &sip_tls_desc.local_address)) {
+ add_sip_domain(ast_sockaddr_stringify(&sip_tcp_desc.local_address),
+ SIP_DOMAIN_AUTO, NULL);
+ }
/* Our extern IP address, if configured */
- if (externip.sin_addr.s_addr)
- add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL);
+ if (!ast_sockaddr_isnull(&externip)) {
+ add_sip_domain(ast_sockaddr_stringify(&externip), SIP_DOMAIN_AUTO,
+ NULL);
+ }
/* Extern host name (NAT traversal support) */
if (!ast_strlen_zero(externhost))
@@ -26698,15 +26808,23 @@ static int reload_config(enum channelreloadreason reason)
static int apply_directmedia_ha(struct sip_pvt *p, const char *op)
{
- struct sockaddr_in us = {0,}, them = {0,};
- int res;
+ struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, };
+ struct sockaddr_in them_sin;
+ int res = AST_SENSE_ALLOW;
ast_rtp_instance_get_remote_address(p->rtp, &them);
ast_rtp_instance_get_local_address(p->rtp, &us);
- if (!(res = ast_apply_ha(p->directmediaha, &them))) {
+ /* Currently ast_apply_ha doesn't support IPv6 */
+ if (ast_sockaddr_is_ipv6(&them)) {
+ return res;
+ }
+
+ ast_sockaddr_to_sin(&them, &them_sin);
+
+ if ((res = ast_apply_ha(p->directmediaha, &them_sin)) == AST_SENSE_DENY) {
ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n",
- op, ast_inet_ntoa(them.sin_addr), ast_inet_ntoa(us.sin_addr));
+ op, ast_sockaddr_stringify(&them), ast_sockaddr_stringify(&us));
}
return res;
@@ -26744,11 +26862,14 @@ static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl)
else
memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
+ struct sockaddr_in ourip_sin;
+ ast_sockaddr_to_sin(&p->ourip, &ourip_sin);
if (!p->pendinginvite) {
- ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
+ ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : ourip_sin.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
+
transmit_reinvite_with_sdp(p, TRUE, FALSE);
} else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
- ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
+ ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : ourip_sin.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
}
}
@@ -26886,19 +27007,19 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i
if (instance) {
changed |= ast_rtp_instance_get_remote_address(instance, &p->redirip);
- } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
+ } else if (!ast_sockaddr_isnull(&p->redirip)) {
memset(&p->redirip, 0, sizeof(p->redirip));
changed = 1;
}
if (vinstance) {
changed |= ast_rtp_instance_get_remote_address(vinstance, &p->vredirip);
- } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
+ } else if (!ast_sockaddr_isnull(&p->vredirip)) {
memset(&p->vredirip, 0, sizeof(p->vredirip));
changed = 1;
}
if (tinstance) {
changed |= ast_rtp_instance_get_remote_address(tinstance, &p->tredirip);
- } else if (p->tredirip.sin_addr.s_addr || ntohs(p->tredirip.sin_port) != 0) {
+ } else if (!ast_sockaddr_isnull(&p->tredirip)) {
memset(&p->tredirip, 0, sizeof(p->tredirip));
changed = 1;
}
@@ -26910,12 +27031,12 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i
if (chan->_state != AST_STATE_UP) { /* We are in early state */
if (p->do_history)
append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
- ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(instance ? p->redirip.sin_addr : p->ourip.sin_addr));
+ ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
} else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */
- ast_debug(3, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(instance ? p->redirip.sin_addr : p->ourip.sin_addr));
+ ast_debug(3, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
transmit_reinvite_with_sdp(p, FALSE, FALSE);
} else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
- ast_debug(3, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(instance ? p->redirip.sin_addr : p->ourip.sin_addr));
+ ast_debug(3, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
/* We have a pending Invite. Send re-invite when we're done with the invite */
ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
}
@@ -27321,6 +27442,40 @@ static int reload(void)
return 1;
}
+/*! \brief Return the first entry from ast_sockaddr_resolve filtered by address family
+ *
+ * \warn Using this function probably means you have a faulty design.
+ */
+static int ast_sockaddr_resolve_first_af(struct ast_sockaddr *addr,
+ const char* name, int flag, int family)
+{
+ struct ast_sockaddr *addrs;
+ int addrs_cnt;
+
+ addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family);
+ if (addrs_cnt <= 0) {
+ return 1;
+ }
+ if (addrs_cnt > 1) {
+ ast_log(LOG_DEBUG, "Multiple addresses, using the first one only\n");
+ }
+
+ ast_sockaddr_copy(addr, &addrs[0]);
+
+ ast_free(addrs);
+ return 0;
+}
+
+/*! \brief Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr
+ *
+ * \warn Using this function probably means you have a faulty design.
+ */
+static int ast_sockaddr_resolve_first(struct ast_sockaddr *addr,
+ const char* name, int flag)
+{
+ return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(&bindaddr));
+}
+
/*! \brief
* \note The only member of the peer used here is the name field
*/
@@ -27342,16 +27497,26 @@ static int peer_cmp_cb(void *obj, void *arg, int flags)
}
/*!
- * \note the peer's ip address field is used to create key.
+ * Hash function based on the the peer's ip address. For IPv6, we use the end
+ * of the address.
+ * \todo Find a better hashing function
*/
static int peer_iphash_cb(const void *obj, const int flags)
{
const struct sip_peer *peer = obj;
- int ret1 = peer->addr.sin_addr.s_addr;
- if (ret1 < 0)
- ret1 = -ret1;
+ int ret = 0;
+
+ if (ast_sockaddr_isnull(&peer->addr)) {
+ ast_log(LOG_ERROR, "Empty address\n");
+ }
- return ret1;
+ ret = ast_sockaddr_hash(&peer->addr);
+
+ if (ret < 0) {
+ ret = -ret;
+ }
+
+ return ret;
}
/*!
@@ -27376,7 +27541,7 @@ static int peer_ipcmp_cb(void *obj, void *arg, int flags)
{
struct sip_peer *peer = obj, *peer2 = arg;
- if (peer->addr.sin_addr.s_addr != peer2->addr.sin_addr.s_addr) {
+ if (ast_sockaddr_cmp_addr(&peer->addr, &peer2->addr)) {
/* IP doesn't match */
return 0;
}
@@ -27393,7 +27558,8 @@ static int peer_ipcmp_cb(void *obj, void *arg, int flags)
}
/* Now only return a match if the port matches, as well. */
- return peer->addr.sin_port == peer2->addr.sin_port ? (CMP_MATCH | CMP_STOP) : 0;
+ return ast_sockaddr_port(&peer->addr) == ast_sockaddr_port(&peer2->addr) ?
+ (CMP_MATCH | CMP_STOP) : 0;
}
@@ -27401,7 +27567,7 @@ static int threadt_hash_cb(const void *obj, const int flags)
{
const struct sip_threadinfo *th = obj;
- return (int) th->tcptls_session->remote_address.sin_addr.s_addr;
+ return ast_sockaddr_hash(&th->tcptls_session->remote_address);
}
static int threadt_cmp_cb(void *obj, void *arg, int flags)
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 2c0224a7c..6ddc3f0cf 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -2804,6 +2804,8 @@ static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *r
struct ast_format_list fmt;
struct sockaddr_in us = { 0, };
struct sockaddr_in them = { 0, };
+ struct ast_sockaddr them_tmp;
+ struct ast_sockaddr us_tmp;
sub = c->tech_pvt;
@@ -2818,7 +2820,8 @@ static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *r
d = l->device;
if (rtp){
- ast_rtp_instance_get_remote_address(rtp, &them);
+ ast_rtp_instance_get_remote_address(rtp, &them_tmp);
+ ast_sockaddr_to_sin(&them_tmp, &them);
/* Shutdown any early-media or previous media on re-invite */
transmit_stopmediatransmission(d, sub);
@@ -2832,7 +2835,8 @@ static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *r
ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms);
if (!(l->directmedia) || (l->nat)){
- ast_rtp_instance_get_local_address(rtp, &us);
+ ast_rtp_instance_get_local_address(rtp, &us_tmp);
+ ast_sockaddr_to_sin(&us_tmp, &us);
us.sin_addr.s_addr = us.sin_addr.s_addr ? us.sin_addr.s_addr : d->ourip.s_addr;
transmit_startmediatransmission(d, sub, us, fmt);
} else {
@@ -3702,12 +3706,14 @@ static void start_rtp(struct skinny_subchannel *sub)
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
int hasvideo = 0;
+ struct ast_sockaddr bindaddr_tmp;
ast_mutex_lock(&sub->lock);
/* Allocate the RTP */
- sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr, NULL);
+ ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
+ sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
if (hasvideo)
- sub->vrtp = ast_rtp_instance_new("asterisk", sched, &bindaddr, NULL);
+ sub->vrtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
if (sub->rtp) {
ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1);
@@ -5603,6 +5609,8 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
struct ast_format_list fmt;
struct sockaddr_in sin = { 0, };
struct sockaddr_in us = { 0, };
+ struct ast_sockaddr sin_tmp;
+ struct ast_sockaddr us_tmp;
uint32_t addr;
int port;
int status;
@@ -5629,8 +5637,10 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
l = sub->parent;
if (sub->rtp) {
- ast_rtp_instance_set_remote_address(sub->rtp, &sin);
- ast_rtp_instance_get_local_address(sub->rtp, &us);
+ ast_sockaddr_from_sin(&sin_tmp, &sin);
+ ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
+ ast_rtp_instance_get_local_address(sub->rtp, &us_tmp);
+ ast_sockaddr_to_sin(&us_tmp, &us);
us.sin_addr.s_addr = us.sin_addr.s_addr ? us.sin_addr.s_addr : d->ourip.s_addr;
} else {
ast_log(LOG_ERROR, "No RTP structure, this is very bad\n");
@@ -6802,9 +6812,13 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
}
} else if (!strcasecmp(v->name, "host")) {
if (type & (TYPE_DEVICE)) {
- if (ast_get_ip(&CDEV->addr, v->value)) {
+ struct ast_sockaddr CDEV_addr_tmp;
+
+ if (ast_get_ip(&CDEV_addr_tmp, v->value)) {
ast_log(LOG_WARNING, "Bad IP '%s' at line %d.\n", v->value, v->lineno);
}
+ ast_sockaddr_to_sin(&CDEV_addr_tmp,
+ &CDEV->addr);
continue;
}
} else if (!strcasecmp(v->name, "port")) {
diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c
index 0ebf879a1..18b76c5e8 100644
--- a/channels/chan_unistim.c
+++ b/channels/chan_unistim.c
@@ -2038,6 +2038,9 @@ static void start_rtp(struct unistim_subchannel *sub)
struct sockaddr_in sin = { 0, };
format_t codec;
struct sockaddr_in sout = { 0, };
+ struct ast_sockaddr us_tmp;
+ struct ast_sockaddr sin_tmp;
+ struct ast_sockaddr sout_tmp;
/* Sanity checks */
if (!sub) {
@@ -2062,7 +2065,8 @@ static void start_rtp(struct unistim_subchannel *sub)
/* Allocate the RTP */
if (unistimdebug)
ast_verb(0, "Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr));
- sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout, NULL);
+ ast_sockaddr_from_sin(&sout_tmp, &sout);
+ sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout_tmp, NULL);
if (!sub->rtp) {
ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n",
strerror(errno), ast_inet_ntoa(sout.sin_addr));
@@ -2078,13 +2082,15 @@ static void start_rtp(struct unistim_subchannel *sub)
ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, sub->parent->parent->nat);
/* Create the RTP connection */
- ast_rtp_instance_get_local_address(sub->rtp, &us);
+ ast_rtp_instance_get_local_address(sub->rtp, &us_tmp);
+ ast_sockaddr_to_sin(&us_tmp, &us);
sin.sin_family = AF_INET;
/* Setting up RTP for our side */
memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
sizeof(sin.sin_addr));
sin.sin_port = htons(sub->parent->parent->rtp_port);
- ast_rtp_instance_set_remote_address(sub->rtp, &sin);
+ ast_sockaddr_from_sin(&sin_tmp, &sin);
+ ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
if (!(sub->owner->nativeformats & sub->owner->readformat)) {
format_t fmt;
char tmp[256];
diff --git a/channels/sip/dialplan_functions.c b/channels/sip/dialplan_functions.c
index d09627ed8..6e1f65b84 100644
--- a/channels/sip/dialplan_functions.c
+++ b/channels/sip/dialplan_functions.c
@@ -62,9 +62,9 @@ int sip_acf_channel_read(struct ast_channel *chan, const char *funcname, char *p
}
if (!strcasecmp(args.param, "peerip")) {
- ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", buflen);
+ ast_copy_string(buf, ast_sockaddr_isnull(&p->sa) ? "" : ast_sockaddr_stringify_addr(&p->sa), buflen);
} else if (!strcasecmp(args.param, "recvip")) {
- ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", buflen);
+ ast_copy_string(buf, ast_sockaddr_isnull(&p->recv) ? "" : ast_sockaddr_stringify_addr(&p->recv), buflen);
} else if (!strcasecmp(args.param, "from")) {
ast_copy_string(buf, p->from, buflen);
} else if (!strcasecmp(args.param, "uri")) {
@@ -76,7 +76,7 @@ int sip_acf_channel_read(struct ast_channel *chan, const char *funcname, char *p
} else if (!strcasecmp(args.param, "t38passthrough")) {
ast_copy_string(buf, (p->t38.state == T38_DISABLED) ? "0" : "1", buflen);
} else if (!strcasecmp(args.param, "rtpdest")) {
- struct sockaddr_in sin;
+ struct ast_sockaddr addr;
struct ast_rtp_instance *stream;
if (ast_strlen_zero(args.type))
@@ -96,10 +96,10 @@ int sip_acf_channel_read(struct ast_channel *chan, const char *funcname, char *p
return 0;
}
- ast_rtp_instance_get_remote_address(stream, &sin);
- snprintf(buf, buflen, "%s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
+ ast_rtp_instance_get_remote_address(stream, &addr);
+ snprintf(buf, buflen, "%s", ast_sockaddr_stringify(&addr));
} else if (!strcasecmp(args.param, "rtpsource")) {
- struct sockaddr_in sin;
+ struct ast_sockaddr sa;
struct ast_rtp_instance *stream;
if (ast_strlen_zero(args.type))
@@ -119,15 +119,15 @@ int sip_acf_channel_read(struct ast_channel *chan, const char *funcname, char *p
return 0;
}
- ast_rtp_instance_get_local_address(stream, &sin);
+ ast_rtp_instance_get_local_address(stream, &sa);
- if (!sin.sin_addr.s_addr) {
- struct sockaddr_in dest_sin;
- ast_rtp_instance_get_remote_address(stream, &dest_sin);
- ast_ouraddrfor(&dest_sin.sin_addr, &sin.sin_addr);
+ if (ast_sockaddr_isnull(&sa)) {
+ struct ast_sockaddr dest_sa;
+ ast_rtp_instance_get_remote_address(stream, &dest_sa);
+ ast_ouraddrfor(&dest_sa, &sa);
}
- snprintf(buf, buflen, "%s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
+ snprintf(buf, buflen, "%s", ast_sockaddr_stringify(&sa));
} else if (!strcasecmp(args.param, "rtpqos")) {
struct ast_rtp_instance *rtp = NULL;
@@ -225,7 +225,7 @@ int sip_acf_channel_read(struct ast_channel *chan, const char *funcname, char *p
}
#ifdef TEST_FRAMEWORK
-static int test_sip_rtpqos_1_new(struct ast_rtp_instance *instance, struct sched_context *sched, struct sockaddr_in *sin, void *data)
+static int test_sip_rtpqos_1_new(struct ast_rtp_instance *instance, struct sched_context *sched, struct ast_sockaddr *addr, void *data)
{
/* Needed to pass sanity checks */
ast_rtp_instance_set_data(instance, data);
@@ -268,7 +268,7 @@ AST_TEST_DEFINE(test_sip_rtpqos_1)
.write = test_sip_rtpqos_1_write,
.get_stat = test_sip_rtpqos_1_get_stat,
};
- struct sockaddr_in sin = { .sin_port = 31337, .sin_addr = { .s_addr = 4 * 16777216 + 3 * 65536 + 2 * 256 + 1 } };
+ struct ast_sockaddr sa = { {0, } };
struct ast_rtp_instance_stats mine = { 0, };
struct sip_pvt *p = NULL;
struct ast_channel *chan = NULL;
@@ -331,11 +331,12 @@ AST_TEST_DEFINE(test_sip_rtpqos_1)
res = AST_TEST_NOT_RUN;
goto done;
}
+
if (!(p->rtp = ast_rtp_instance_new("test", sched, &bindaddr, &mine))) {
res = AST_TEST_NOT_RUN;
goto done;
}
- ast_rtp_instance_set_remote_address(p->rtp, &sin);
+ ast_rtp_instance_set_remote_address(p->rtp, &sa);
if (!(chan = ast_dummy_channel_alloc())) {
res = AST_TEST_NOT_RUN;
goto done;
diff --git a/channels/sip/include/dialog.h b/channels/sip/include/dialog.h
index 8972c02d9..ed31b7774 100644
--- a/channels/sip/include/dialog.h
+++ b/channels/sip/include/dialog.h
@@ -34,7 +34,7 @@
struct sip_pvt *dialog_ref_debug(struct sip_pvt *p, char *tag, char *file, int line, const char *func);
struct sip_pvt *dialog_unref_debug(struct sip_pvt *p, char *tag, char *file, int line, const char *func);
-struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
+struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *sin,
int useglobal_nat, const int intended_method, struct sip_request *req);
void sip_scheddestroy_final(struct sip_pvt *p, int ms);
void sip_scheddestroy(struct sip_pvt *p, int ms);
diff --git a/channels/sip/include/globals.h b/channels/sip/include/globals.h
index 0d7131d87..414d2189b 100644
--- a/channels/sip/include/globals.h
+++ b/channels/sip/include/globals.h
@@ -24,7 +24,7 @@
#ifndef _SIP_GLOBALS_H
#define _SIP_GLOBALS_H
-extern struct sockaddr_in bindaddr; /*!< UDP: The address we bind to */
+extern struct ast_sockaddr bindaddr; /*!< UDP: The address we bind to */
extern struct sched_context *sched; /*!< The scheduling context */
/*! \brief Definition of this channel for PBX channel registration */
diff --git a/channels/sip/include/reqresp_parser.h b/channels/sip/include/reqresp_parser.h
index 58784a621..d8631c982 100644
--- a/channels/sip/include/reqresp_parser.h
+++ b/channels/sip/include/reqresp_parser.h
@@ -28,7 +28,7 @@
* \note
* - Multiple scheme's can be specified ',' delimited. ex: "sip:,sips:"
* - If a component is not requested, do not split around it. This means
- * that if we don't have domain, we cannot split name:pass and domain:port.
+ * that if we don't have domain, we cannot split name:pass.
* - It is safe to call with ret_name, pass, domain, port pointing all to
* the same place.
* - If no secret parameter is provided, ret_name will return with both parts, user:secret
@@ -42,7 +42,8 @@
* general form we are expecting is sip:user:password;user-parameters@host:port;uri-parameters?headers
* \endverbatim
*/
-int parse_uri(char *uri, const char *scheme, char **ret_name, char **pass, char **domain, char **port, char **transport);
+int parse_uri(char *uri, const char *scheme, char **ret_name, char **pass,
+ char **domain, char **transport);
/*!
* \brief parses a URI in to all of its components and any trailing residue
@@ -51,7 +52,9 @@ int parse_uri(char *uri, const char *scheme, char **ret_name, char **pass, char
* \retval -1 on error.
*
*/
-int parse_uri_full(char *uri, const char *scheme, char **user, char **pass, char **host, char **port, struct uriparams *params, char **headers, char **residue);
+int parse_uri_full(char *uri, const char *scheme, char **user, char **pass,
+ char **domain, struct uriparams *params, char **headers,
+ char **residue);
/*!
* \brief Get caller id name from SIP headers, copy into output buffer
@@ -100,7 +103,10 @@ int get_in_brackets_full(char *tmp, char **out, char **residue);
* \retval 0 success
* \retval -1 failure
*/
-int parse_name_andor_addr(char *uri, const char *scheme, char **name, char **user, char **pass, char **host, char **port, struct uriparams *params, char **headers, char **remander);
+int parse_name_andor_addr(char *uri, const char *scheme, char **name,
+ char **user, char **pass, char **domain,
+ struct uriparams *params, char **headers,
+ char **remander);
/*! \brief Parse all contact header contacts
* \retval 0 success
diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h
index 13527517f..92fa68e82 100644
--- a/channels/sip/include/sip.h
+++ b/channels/sip/include/sip.h
@@ -646,7 +646,8 @@ enum sip_tcptls_alert {
*/
struct sip_proxy {
char name[MAXHOSTNAMELEN]; /*!< DNS name of domain/host or IP */
- struct sockaddr_in ip; /*!< Currently used IP address and port */
+ struct ast_sockaddr ip; /*!< Currently used IP address and port */
+ int port;
time_t last_dnsupdate; /*!< When this was resolved */
enum sip_transport transport;
int force; /*!< If it's an outbound proxy, Force use of this outbound proxy for all outbound requests */
@@ -702,6 +703,7 @@ struct sip_settings {
char default_subscribecontext[AST_MAX_CONTEXT];
struct ast_ha *contact_ha; /*! \brief Global list of addresses dynamic peers are not allowed to use */
format_t capability; /*!< Supported codecs */
+ int tcp_enabled;
};
/*! \brief The SIP socket definition */
@@ -1008,16 +1010,16 @@ struct sip_pvt {
long invite_branch; /*!< The branch used when we sent the initial INVITE */
int64_t sessionversion_remote; /*!< Remote UA's SDP Session Version */
unsigned int portinuri:1; /*!< Non zero if a port has been specified, will also disable srv lookups */
- struct sockaddr_in sa; /*!< Our peer */
- struct sockaddr_in redirip; /*!< Where our RTP should be going if not to us */
- struct sockaddr_in vredirip; /*!< Where our Video RTP should be going if not to us */
- struct sockaddr_in tredirip; /*!< Where our Text RTP should be going if not to us */
+ struct ast_sockaddr sa; /*!< Our peer */
+ struct ast_sockaddr redirip; /*!< Where our RTP should be going if not to us */
+ struct ast_sockaddr vredirip; /*!< Where our Video RTP should be going if not to us */
+ struct ast_sockaddr tredirip; /*!< Where our Text RTP should be going if not to us */
time_t lastrtprx; /*!< Last RTP received */
time_t lastrtptx; /*!< Last RTP sent */
int rtptimeout; /*!< RTP timeout time */
struct ast_ha *directmediaha; /*!< Which IPs are allowed to interchange direct media with this peer - copied from sip_peer */
- struct sockaddr_in recv; /*!< Received as */
- struct sockaddr_in ourip; /*!< Our IP (as seen from the outside) */
+ struct ast_sockaddr recv; /*!< Received as */
+ struct ast_sockaddr ourip; /*!< Our IP (as seen from the outside) */
enum transfermodes allowtransfer; /*!< REFER: restriction scheme */
struct ast_channel *owner; /*!< Who owns us (if we have an owner) */
struct sip_route *route; /*!< Head of linked list of routing steps (fm Record-Route) */
@@ -1209,7 +1211,7 @@ struct sip_peer {
ast_group_t pickupgroup; /*!< Pickup group */
struct sip_proxy *outboundproxy;/*!< Outbound proxy for this peer */
struct ast_dnsmgr_entry *dnsmgr;/*!< DNS refresh manager for peer */
- struct sockaddr_in addr; /*!< IP address of peer */
+ struct ast_sockaddr addr; /*!< IP address of peer */
unsigned int portinuri:1; /*!< Whether the port should be included in the URI */
struct sip_pvt *call; /*!< Call pointer */
int pokeexpire; /*!< Qualification: When to expire poke (qualify= checking) */
@@ -1217,7 +1219,7 @@ struct sip_peer {
int maxms; /*!< Qualification: Max ms we will accept for the host to be up, 0 to not monitor */
int qualifyfreq; /*!< Qualification: Qualification: How often to check for the host to be up */
struct timeval ps; /*!< Qualification: Time for sending SIP OPTION in sip_pke_peer() */
- struct sockaddr_in defaddr; /*!< Default IP address, used until registration */
+ struct ast_sockaddr defaddr; /*!< Default IP address, used until registration */
struct ast_ha *ha; /*!< Access control list */
struct ast_ha *contactha; /*!< Restrict what IPs are allowed in the Contact header (for registration) */
struct ast_ha *directmediaha; /*!< Restrict what IPs are allowed to interchange direct media with */
@@ -1281,7 +1283,7 @@ struct sip_registry {
int callid_valid; /*!< 0 means we haven't chosen callid for this registry yet. */
unsigned int ocseq; /*!< Sequence number we got to for REGISTERs for this registry */
struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager for register */
- struct sockaddr_in us; /*!< Who the server thinks we are */
+ struct ast_sockaddr us; /*!< Who the server thinks we are */
int noncecount; /*!< Nonce-count */
char lastmsg[256]; /*!< Last Message sent/received */
};
@@ -1321,7 +1323,7 @@ struct sip_subscription_mwi {
unsigned int subscribed:1; /*!< Whether we are currently subscribed or not */
struct sip_pvt *call; /*!< Outbound subscription dialog */
struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager for subscription */
- struct sockaddr_in us; /*!< Who the server thinks we are */
+ struct ast_sockaddr us; /*!< Who the server thinks we are */
};
/*!
@@ -1697,8 +1699,7 @@ struct contact {
char *name;
char *user;
char *pass;
- char *host;
- char *port;
+ char *domain;
struct uriparams params;
char *headers;
char *expires;
diff --git a/channels/sip/reqresp_parser.c b/channels/sip/reqresp_parser.c
index bf35bc226..59cefaa46 100644
--- a/channels/sip/reqresp_parser.c
+++ b/channels/sip/reqresp_parser.c
@@ -28,7 +28,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "include/reqresp_parser.h"
/*! \brief * parses a URI in its components.*/
-int parse_uri_full(char *uri, const char *scheme, char **user, char **pass, char **host, char **port, struct uriparams *params, char **headers, char **residue)
+int parse_uri_full(char *uri, const char *scheme, char **user, char **pass,
+ char **domain, struct uriparams *params, char **headers,
+ char **residue)
{
char *userinfo = NULL;
char *parameters = NULL;
@@ -58,31 +60,24 @@ int parse_uri_full(char *uri, const char *scheme, char **user, char **pass, char
}
}
- if (!host) {
- /* if we don't want to split around host, keep everything as a userinfo - cos thats how old parse_uri operated*/
+ if (!domain) {
+ /* if we don't want to split around domain, keep everything as a
+ * userinfo - cos thats how old parse_uri operated*/
userinfo = uri;
} else {
- char *hostport;
+ char *dom = "";
if ((c = strchr(uri, '@'))) {
*c++ = '\0';
- hostport = c;
+ dom = c;
userinfo = uri;
- uri = hostport; /* userinfo can contain ? and ; chars so step forward before looking for params and headers */
+ uri = c; /* userinfo can contain ? and ; chars so step forward before looking for params and headers */
} else {
/* domain-only URI, according to the SIP RFC. */
- hostport = uri;
+ dom = uri;
userinfo = "";
}
- if (port && (c = strchr(hostport, ':'))) { /* Remove :port */
- *c++ = '\0';
- *port = c;
- uri = c;
- } else if (port) {
- *port = "";
- }
-
- *host = hostport;
+ *domain = dom;
}
if (pass && (c = strchr(userinfo, ':'))) { /* user:password */
@@ -201,7 +196,7 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
{
int res = AST_TEST_PASS;
char uri[1024];
- char *user, *pass, *host, *port, *headers, *residue;
+ char *user, *pass, *domain, *headers, *residue;
struct uriparams params;
struct testdata {
@@ -209,15 +204,13 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
char *uri;
char **userptr;
char **passptr;
- char **hostptr;
- char **portptr;
+ char **domainptr;
char **headersptr;
char **residueptr;
struct uriparams *paramsptr;
char *user;
char *pass;
- char *host;
- char *port;
+ char *domain;
char *headers;
char *residue;
struct uriparams params;
@@ -234,17 +227,15 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
.uri = "sip:user:secret@host:5060;param=discard;transport=tcp;param2=residue",
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.user = "user",
.pass = "secret",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "",
- .residue = "param2=residue",
+ .residue = "param2=residue",
.params.transport = "tcp",
.params.lr = 0,
.params.user = ""
@@ -255,15 +246,13 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
.uri = "sip:user:secret@host:5060;param=discard;transport=tcp;param2=discard2?header=blah&header2=blah2;param3=residue",
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.user = "user",
.pass = "secret",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "header=blah&header2=blah2",
.residue = "param3=residue",
.params.transport = "tcp",
@@ -276,15 +265,13 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
.uri = "sip:-_.!~*'()&=+$,;?/:secret@host:5060;transport=tcp",
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.user = "-_.!~*'()&=+$,;?/",
.pass = "secret",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "",
.residue = "",
.params.transport = "tcp",
@@ -297,15 +284,13 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
.uri = "sip:user:-_.!~*'()&=+$,@host:5060;transport=tcp",
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.user = "user",
.pass = "-_.!~*'()&=+$,",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "",
.residue = "",
.params.transport = "tcp",
@@ -318,15 +303,13 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
.uri = "sip:user:secret@1-1.a-1.:5060;transport=tcp",
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.user = "user",
.pass = "secret",
- .host = "1-1.a-1.",
- .port = "5060",
+ .domain = "1-1.a-1.:5060",
.headers = "",
.residue = "",
.params.transport = "tcp",
@@ -339,15 +322,13 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
.uri = "sip:user:secret@host:5060;-_.!~*'()[]/:&+$=-_.!~*'()[]/:&+$;transport=tcp",
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.user = "user",
.pass = "secret",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "",
.residue = "",
.params.transport = "tcp",
@@ -360,15 +341,13 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
.uri = "sip:user:secret@host:5060;-_.!~*'()[]/:&+$=-_.!~*'()[]/:&+$?header=blah&header2=blah2;-_.!~*'()[]/:&+$=residue",
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.user = "user",
.pass = "secret",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "header=blah&header2=blah2",
.residue = "-_.!~*'()[]/:&+$=residue",
.params.transport = "",
@@ -381,15 +360,13 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
.uri = "sip:user:secret@host:5060;param=discard;lr?header=blah",
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.user = "user",
.pass = "secret",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "header=blah",
.residue = "",
.params.transport = "",
@@ -402,15 +379,13 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
.uri = "sip:user:secret@host:5060;param=discard;lr=yes?header=blah",
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.user = "user",
.pass = "secret",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "header=blah",
.residue = "",
.params.transport = "",
@@ -423,15 +398,13 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
.uri = "sip:user:secret@host:5060;paramlr=lr;lr=no;lr=off;lr=0;lr=;=lr;lrextra;lrparam2=lr?header=blah",
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.user = "user",
.pass = "secret",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "header=blah",
.residue = "",
.params.transport = "",
@@ -466,16 +439,19 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
}
AST_LIST_TRAVERSE(&testdatalist, testdataptr, list) {
- user = pass = host = port = headers = residue = NULL;
+ user = pass = domain = headers = residue = NULL;
params.transport = params.user = params.method = params.ttl = params.maddr = NULL;
params.lr = 0;
ast_copy_string(uri,testdataptr->uri,sizeof(uri));
- if (parse_uri_full(uri, "sip:,sips:", testdataptr->userptr, testdataptr->passptr, testdataptr->hostptr, testdataptr->portptr, testdataptr->paramsptr, testdataptr->headersptr, testdataptr->residueptr) ||
+ if (parse_uri_full(uri, "sip:,sips:", testdataptr->userptr,
+ testdataptr->passptr, testdataptr->domainptr,
+ testdataptr->paramsptr,
+ testdataptr->headersptr,
+ testdataptr->residueptr) ||
((testdataptr->userptr) && strcmp(testdataptr->user, user)) ||
((testdataptr->passptr) && strcmp(testdataptr->pass, pass)) ||
- ((testdataptr->hostptr) && strcmp(testdataptr->host, host)) ||
- ((testdataptr->portptr) && strcmp(testdataptr->port, port)) ||
+ ((testdataptr->domainptr) && strcmp(testdataptr->domain, domain)) ||
((testdataptr->headersptr) && strcmp(testdataptr->headers, headers)) ||
((testdataptr->residueptr) && strcmp(testdataptr->residue, residue)) ||
((testdataptr->paramsptr) && strcmp(testdataptr->params.transport,params.transport)) ||
@@ -492,13 +468,14 @@ AST_TEST_DEFINE(sip_parse_uri_fully_test)
}
-int parse_uri(char *uri, const char *scheme, char **user, char **pass, char **host, char **port, char **transport) {
+int parse_uri(char *uri, const char *scheme, char **user, char **pass,
+ char **domain, char **transport) {
int ret;
char *headers;
struct uriparams params;
headers = NULL;
- ret = parse_uri_full(uri, scheme, user, pass, host, port, &params, &headers, NULL);
+ ret = parse_uri_full(uri, scheme, user, pass, domain, &params, &headers, NULL);
if (transport) {
*transport=params.transport;
}
@@ -508,7 +485,7 @@ int parse_uri(char *uri, const char *scheme, char **user, char **pass, char **ho
AST_TEST_DEFINE(sip_parse_uri_test)
{
int res = AST_TEST_PASS;
- char *name, *pass, *domain, *port, *transport;
+ char *name, *pass, *domain, *transport;
char uri1[] = "sip:name@host";
char uri2[] = "sip:name@host;transport=tcp";
char uri3[] = "sip:name:secret@host;transport=tcp";
@@ -535,70 +512,66 @@ AST_TEST_DEFINE(sip_parse_uri_test)
}
/* Test 1, simple URI */
- name = pass = domain = port = transport = NULL;
- if (parse_uri(uri1, "sip:,sips:", &name, &pass, &domain, &port, &transport) ||
+ name = pass = domain = transport = NULL;
+ if (parse_uri(uri1, "sip:,sips:", &name, &pass, &domain, &transport) ||
strcmp(name, "name") ||
!ast_strlen_zero(pass) ||
strcmp(domain, "host") ||
- !ast_strlen_zero(port) ||
!ast_strlen_zero(transport)) {
ast_test_status_update(test, "Test 1: simple uri failed. \n");
res = AST_TEST_FAIL;
}
/* Test 2, add tcp transport */
- name = pass = domain = port = transport = NULL;
- if (parse_uri(uri2, "sip:,sips:", &name, &pass, &domain, &port, &transport) ||
+ name = pass = domain = transport = NULL;
+ if (parse_uri(uri2, "sip:,sips:", &name, &pass, &domain, &transport) ||
strcmp(name, "name") ||
!ast_strlen_zero(pass) ||
strcmp(domain, "host") ||
- !ast_strlen_zero(port) ||
strcmp(transport, "tcp")) {
ast_test_status_update(test, "Test 2: uri with addtion of tcp transport failed. \n");
res = AST_TEST_FAIL;
}
/* Test 3, add secret */
- name = pass = domain = port = transport = NULL;
- if (parse_uri(uri3, "sip:,sips:", &name, &pass, &domain, &port, &transport) ||
+ name = pass = domain = transport = NULL;
+ if (parse_uri(uri3, "sip:,sips:", &name, &pass, &domain, &transport) ||
strcmp(name, "name") ||
strcmp(pass, "secret") ||
strcmp(domain, "host") ||
- !ast_strlen_zero(port) ||
strcmp(transport, "tcp")) {
ast_test_status_update(test, "Test 3: uri with addition of secret failed.\n");
res = AST_TEST_FAIL;
}
/* Test 4, add port and unparsed header field*/
- name = pass = domain = port = transport = NULL;
- if (parse_uri(uri4, "sip:,sips:", &name, &pass, &domain, &port, &transport) ||
+ name = pass = domain = transport = NULL;
+ if (parse_uri(uri4, "sip:,sips:", &name, &pass, &domain, &transport) ||
strcmp(name, "name") ||
strcmp(pass, "secret") ||
- strcmp(domain, "host") ||
- strcmp(port, "port") ||
+ strcmp(domain, "host:port") ||
strcmp(transport, "tcp")) {
ast_test_status_update(test, "Test 4: add port and unparsed header field failed.\n");
res = AST_TEST_FAIL;
}
/* Test 5, verify parse_uri does not crash when given a NULL uri */
- name = pass = domain = port = transport = NULL;
- if (!parse_uri(NULL, "sip:,sips:", &name, &pass, &domain, &port, &transport)) {
+ name = pass = domain = transport = NULL;
+ if (!parse_uri(NULL, "sip:,sips:", &name, &pass, &domain, &transport)) {
ast_test_status_update(test, "Test 5: passing a NULL uri failed.\n");
res = AST_TEST_FAIL;
}
/* Test 6, verify parse_uri does not crash when given a NULL output parameters */
- name = pass = domain = port = transport = NULL;
- if (parse_uri(uri6, "sip:,sips:", NULL, NULL, NULL, NULL, NULL)) {
+ name = pass = domain = transport = NULL;
+ if (parse_uri(uri6, "sip:,sips:", NULL, NULL, NULL, NULL)) {
ast_test_status_update(test, "Test 6: passing NULL output parameters failed.\n");
res = AST_TEST_FAIL;
}
- /* Test 7, verify parse_uri returns user:secret and domain:port when no port or secret output parameters are supplied. */
- name = pass = domain = port = transport = NULL;
- if (parse_uri(uri7, "sip:,sips:", &name, NULL, &domain, NULL, NULL) ||
+ /* Test 7, verify parse_uri returns user:secret and domain when no port or secret output parameters are supplied. */
+ name = pass = domain = transport = NULL;
+ if (parse_uri(uri7, "sip:,sips:", &name, NULL, &domain, NULL) ||
strcmp(name, "name:secret") ||
strcmp(domain, "host:port")) {
@@ -607,8 +580,8 @@ AST_TEST_DEFINE(sip_parse_uri_test)
}
/* Test 8, verify parse_uri can handle a domain only uri */
- name = pass = domain = port = transport = NULL;
- if (parse_uri(uri8, "sip:,sips:", &name, &pass, &domain, &port, &transport) ||
+ name = pass = domain = transport = NULL;
+ if (parse_uri(uri8, "sip:,sips:", &name, &pass, &domain, &transport) ||
strcmp(domain, "host") ||
!ast_strlen_zero(name)) {
ast_test_status_update(test, "Test 8: add port and unparsed header field failed.\n");
@@ -616,12 +589,11 @@ AST_TEST_DEFINE(sip_parse_uri_test)
}
/* Test 9, add port and unparsed header field with domain only uri*/
- name = pass = domain = port = transport = NULL;
- if (parse_uri(uri9, "sip:,sips:", &name, &pass, &domain, &port, &transport) ||
+ name = pass = domain = transport = NULL;
+ if (parse_uri(uri9, "sip:,sips:", &name, &pass, &domain, &transport) ||
!ast_strlen_zero(name) ||
!ast_strlen_zero(pass) ||
strcmp(domain, "host") ||
- strcmp(port, "port") ||
strcmp(transport, "tcp")) {
ast_test_status_update(test, "Test 9: domain only uri failed \n");
res = AST_TEST_FAIL;
@@ -630,12 +602,11 @@ AST_TEST_DEFINE(sip_parse_uri_test)
/* Test 10, handle invalid/missing "sip:,sips:" scheme
* we expect parse_uri to return an error, but still parse
* the results correctly here */
- name = pass = domain = port = transport = NULL;
- if (!parse_uri(uri10, "sip:,sips:", &name, &pass, &domain, &port, &transport) ||
+ name = pass = domain = transport = NULL;
+ if (!parse_uri(uri10, "sip:,sips:", &name, &pass, &domain, &transport) ||
!ast_strlen_zero(name) ||
!ast_strlen_zero(pass) ||
strcmp(domain, "host") ||
- strcmp(port, "port") ||
strcmp(transport, "tcp")) {
ast_test_status_update(test, "Test 10: missing \"sip:sips:\" scheme failed\n");
res = AST_TEST_FAIL;
@@ -644,12 +615,11 @@ AST_TEST_DEFINE(sip_parse_uri_test)
/* Test 11, simple domain only URI with missing scheme
* we expect parse_uri to return an error, but still parse
* the results correctly here */
- name = pass = domain = port = transport = NULL;
- if (!parse_uri(uri11, "sip:,sips:", &name, &pass, &domain, &port, &transport) ||
+ name = pass = domain = transport = NULL;
+ if (!parse_uri(uri11, "sip:,sips:", &name, &pass, &domain, &transport) ||
!ast_strlen_zero(name) ||
!ast_strlen_zero(pass) ||
strcmp(domain, "host") ||
- !ast_strlen_zero(port) ||
!ast_strlen_zero(transport)) {
ast_test_status_update(test, "Test 11: simple uri with missing scheme failed. \n");
res = AST_TEST_FAIL;
@@ -871,7 +841,7 @@ int get_name_and_number(const char *hdr, char **name, char **number)
tmp_number = get_in_brackets(header);
/* parse out the number here */
- if (parse_uri(tmp_number, "sip:,sips:", &tmp_number, &dummy, &domain, &dummy, NULL) || ast_strlen_zero(tmp_number)) {
+ if (parse_uri(tmp_number, "sip:,sips:", &tmp_number, &dummy, &domain, NULL) || ast_strlen_zero(tmp_number)) {
ast_log(LOG_ERROR, "can not parse name and number from sip header.\n");
return -1;
}
@@ -1149,7 +1119,10 @@ AST_TEST_DEFINE(get_in_brackets_test)
}
-int parse_name_andor_addr(char *uri, const char *scheme, char **name, char **user, char **pass, char **host, char **port, struct uriparams *params, char **headers, char **residue)
+int parse_name_andor_addr(char *uri, const char *scheme, char **name,
+ char **user, char **pass, char **domain,
+ struct uriparams *params, char **headers,
+ char **residue)
{
static char buf[1024];
char **residue2=residue;
@@ -1164,14 +1137,15 @@ int parse_name_andor_addr(char *uri, const char *scheme, char **name, char **use
residue2 = NULL;
}
- return parse_uri_full(uri, scheme, user, pass, host, port, params, headers, residue2);
+ return parse_uri_full(uri, scheme, user, pass, domain, params, headers,
+ residue2);
}
AST_TEST_DEFINE(parse_name_andor_addr_test)
{
int res = AST_TEST_PASS;
char uri[1024];
- char *name, *user, *pass, *host, *port, *headers, *residue;
+ char *name, *user, *pass, *domain, *headers, *residue;
struct uriparams params;
struct testdata {
@@ -1180,16 +1154,14 @@ AST_TEST_DEFINE(parse_name_andor_addr_test)
char **nameptr;
char **userptr;
char **passptr;
- char **hostptr;
- char **portptr;
+ char **domainptr;
char **headersptr;
char **residueptr;
struct uriparams *paramsptr;
char *name;
char *user;
char *pass;
- char *host;
- char *port;
+ char *domain;
char *headers;
char *residue;
struct uriparams params;
@@ -1206,16 +1178,14 @@ AST_TEST_DEFINE(parse_name_andor_addr_test)
.nameptr = &name,
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.name = "name :@ ",
.user = "user",
.pass = "secret",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "",
.residue = "tag=tag",
.params.transport = "tcp",
@@ -1229,16 +1199,14 @@ AST_TEST_DEFINE(parse_name_andor_addr_test)
.nameptr = &name,
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.name = "givenname familyname",
.user = "user",
.pass = "secret",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "",
.residue = "expires=3600",
.params.transport = "tcp",
@@ -1252,16 +1220,14 @@ AST_TEST_DEFINE(parse_name_andor_addr_test)
.nameptr = &name,
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.name = "",
.user = "user",
.pass = "secret",
- .host = "host",
- .port = "5060",
+ .domain = "host:5060",
.headers = "",
.residue = "q=1",
.params.transport = "tcp",
@@ -1275,16 +1241,14 @@ AST_TEST_DEFINE(parse_name_andor_addr_test)
.nameptr = &name,
.userptr = &user,
.passptr = &pass,
- .hostptr = &host,
- .portptr = &port,
+ .domainptr = &domain,
.headersptr = &headers,
.residueptr = &residue,
.paramsptr = &params,
.name = "",
.user = "",
.pass = "",
- .host = "host",
- .port = "",
+ .domain = "host",
.headers = "",
.residue = "",
.params.transport = "",
@@ -1313,16 +1277,22 @@ AST_TEST_DEFINE(parse_name_andor_addr_test)
}
AST_LIST_TRAVERSE(&testdatalist, testdataptr, list) {
- name = user = pass = host = port = headers = residue = NULL;
+ name = user = pass = domain = headers = residue = NULL;
params.transport = params.user = params.method = params.ttl = params.maddr = NULL;
params.lr = 0;
ast_copy_string(uri,testdataptr->uri,sizeof(uri));
- if (parse_name_andor_addr(uri, "sip:,sips:", testdataptr->nameptr, testdataptr->userptr, testdataptr->passptr, testdataptr->hostptr, testdataptr->portptr, testdataptr->paramsptr, testdataptr->headersptr, testdataptr->residueptr) ||
+ if (parse_name_andor_addr(uri, "sip:,sips:",
+ testdataptr->nameptr,
+ testdataptr->userptr,
+ testdataptr->passptr,
+ testdataptr->domainptr,
+ testdataptr->paramsptr,
+ testdataptr->headersptr,
+ testdataptr->residueptr) ||
((testdataptr->nameptr) && strcmp(testdataptr->name, name)) ||
((testdataptr->userptr) && strcmp(testdataptr->user, user)) ||
((testdataptr->passptr) && strcmp(testdataptr->pass, pass)) ||
- ((testdataptr->hostptr) && strcmp(testdataptr->host, host)) ||
- ((testdataptr->portptr) && strcmp(testdataptr->port, port)) ||
+ ((testdataptr->domainptr) && strcmp(testdataptr->domain, domain)) ||
((testdataptr->headersptr) && strcmp(testdataptr->headers, headers)) ||
((testdataptr->residueptr) && strcmp(testdataptr->residue, residue)) ||
((testdataptr->paramsptr) && strcmp(testdataptr->params.transport,params.transport)) ||
@@ -1391,7 +1361,11 @@ int parse_contact_header(char *contactheader, struct contactliststruct *contactl
AST_LIST_HEAD_SET_NOLOCK(contactlist, contact);
while ((last = get_comma(contactheader,&comma)) != -1) {
- res = parse_name_andor_addr(contactheader,"sip:,sips:",&contact->name,&contact->user,&contact->pass,&contact->host,&contact->port,&contact->params,&contact->headers,&residue);
+ res = parse_name_andor_addr(contactheader, "sip:,sips:",
+ &contact->name, &contact->user,
+ &contact->pass, &contact->domain,
+ &contact->params, &contact->headers,
+ &residue);
if (res == -1) {
return res;
}
@@ -1462,8 +1436,7 @@ AST_TEST_DEFINE(parse_contact_header_test)
.name = "name :@;?&,",
.user = "user",
.pass = "secret",
- .host = "host",
- .port = "5082",
+ .domain = "host:5082",
.params.transport = "tcp",
.params.ttl = "",
.params.lr = 0,
@@ -1482,8 +1455,7 @@ AST_TEST_DEFINE(parse_contact_header_test)
.name = "",
.user = ",user1,",
.pass = ",secret1,",
- .host = "host1",
- .port = "",
+ .domain = "host1",
.params.transport = "",
.params.ttl = "7",
.params.lr = 0,
@@ -1495,8 +1467,7 @@ AST_TEST_DEFINE(parse_contact_header_test)
.name = "",
.user = "",
.pass = "",
- .host = "host2",
- .port = "",
+ .domain = "host2",
.params.transport = "",
.params.ttl = "",
.params.lr = 0,
@@ -1552,8 +1523,7 @@ AST_TEST_DEFINE(parse_contact_header_test)
strcmp(tdcontactptr->name, contactptr->name) ||
strcmp(tdcontactptr->user, contactptr->user) ||
strcmp(tdcontactptr->pass, contactptr->pass) ||
- strcmp(tdcontactptr->host, contactptr->host) ||
- strcmp(tdcontactptr->port, contactptr->port) ||
+ strcmp(tdcontactptr->domain, contactptr->domain) ||
strcmp(tdcontactptr->headers, contactptr->headers) ||
strcmp(tdcontactptr->expires, contactptr->expires) ||
strcmp(tdcontactptr->q, contactptr->q) ||