summaryrefslogtreecommitdiff
path: root/channels/chan_sip.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r--channels/chan_sip.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index cdf020ad7..1adf7a00f 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1399,7 +1399,7 @@ static int get_refer_info(struct sip_pvt *transferer, struct sip_request *outgoi
static int get_also_info(struct sip_pvt *p, struct sip_request *oreq);
static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req);
static int set_address_from_contact(struct sip_pvt *pvt);
-static void check_via(struct sip_pvt *p, struct sip_request *req);
+static void check_via(struct sip_pvt *p, const struct sip_request *req);
static int get_rpid(struct sip_pvt *p, struct sip_request *oreq);
static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason, char **reason_str);
static enum sip_get_dest_result get_destination(struct sip_pvt *p, struct sip_request *oreq, int *cc_recall_core_id);
@@ -8747,9 +8747,8 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
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);
ast_sockaddr_copy(&p->recv, addr);
-
+ check_via(p, req);
do_setnat(p);
}
@@ -12116,8 +12115,9 @@ static int transmit_response_using_temp(ast_string_field callid, struct ast_sock
if (useglobal_nat && addr) {
ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT);
+ ast_copy_flags(&p->flags[2], &global_flags[2], SIP_PAGE3_NAT_AUTO_RPORT);
ast_sockaddr_copy(&p->recv, addr);
- do_setnat(p);
+ check_via(p, req);
}
ast_string_field_set(p, fromdomain, default_fromdomain);
@@ -17958,7 +17958,7 @@ static int get_also_info(struct sip_pvt *p, struct sip_request *oreq)
}
/*! \brief check Via: header for hostname, port and rport request/answer */
-static void check_via(struct sip_pvt *p, struct sip_request *req)
+static void check_via(struct sip_pvt *p, const struct sip_request *req)
{
char via[512];
char *c, *maddr;
@@ -18092,6 +18092,21 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
return AUTH_DONT_KNOW;
}
+ /* build_peer, called through sip_find_peer, is not able to check the
+ * sip_pvt->natdetected flag in order to determine if the peer is behind
+ * NAT or not when SIP_PAGE3_NAT_AUTO_RPORT or SIP_PAGE3_NAT_AUTO_COMEDIA
+ * are set on the peer. So we check for that here and set the peer's
+ * address accordingly.
+ */
+ if (p->natdetected && ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
+ ast_set_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT);
+ ast_sockaddr_copy(&peer->addr, &p->recv);
+ }
+
+ if (p->natdetected && ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_COMEDIA)) {
+ ast_set_flag(&peer->flags[1], SIP_PAGE2_SYMMETRICRTP);
+ }
+
if (!ast_apply_acl(peer->acl, addr, "SIP Peer ACL: ")) {
ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
sip_unref_peer(peer, "sip_unref_peer: check_peer_ok: from sip_find_peer call, early return of AUTH_ACL_FAILED");
@@ -28426,7 +28441,10 @@ static int handle_request_do(struct sip_request *req, struct ast_sockaddr *addr)
owner_chan_ref = sip_pvt_lock_full(p);
copy_socket_data(&p->socket, &req->socket);
- ast_sockaddr_copy(&p->recv, addr);
+
+ if (ast_sockaddr_isnull(&p->recv)) { /* This may already be set before getting here */
+ ast_sockaddr_copy(&p->recv, addr);
+ }
/* if we have an owner, then this request has been authenticated */
if (p->owner) {
@@ -30637,7 +30655,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
} else if (!strcasecmp(v->name, "host")) {
if (!strcasecmp(v->value, "dynamic")) {
/* They'll register with us */
- if ((!found && !realtime) || !peer->host_dynamic) {
+ if ((!found && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) || !peer->host_dynamic) {
/* Initialize stuff if this is a new peer, or if it used to
* not be dynamic before the reload. */
ast_sockaddr_setnull(&peer->addr);
@@ -30990,6 +31008,10 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
set_socket_transport(&peer->socket, peer->default_outbound_transport);
}
+ ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
+ ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
+ ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags);
+
if (ast_str_strlen(fullcontact)) {
ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact));
peer->rt_fromcontact = TRUE;
@@ -31083,9 +31105,6 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
sip_poke_peer(peer, 0);
}
- ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
- ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
- ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags);
if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
sip_cfg.allowsubscribe = TRUE; /* No global ban any more */
}