mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-19 08:11:21 +00:00
handle rport/received in Via headers properly (issue #5037)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6582 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -3627,36 +3627,58 @@ static int copy_all_header(struct sip_request *req, struct sip_request *orig, ch
|
|||||||
return copied ? 0 : -1;
|
return copied ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--- copy_via_headers: Copy SIP VIA Headers from one request to another ---*/
|
/*--- copy_via_headers: Copy SIP VIA Headers from the request to the response ---*/
|
||||||
|
/* If the client indicates that it wishes to know the port we received from,
|
||||||
|
it adds ;rport without an argument to the topmost via header. We need to
|
||||||
|
add the port number (from our point of view) to that parameter.
|
||||||
|
We always add ;received=<ip address> to the topmost via header.
|
||||||
|
Received: RFC 3261, rport RFC 3581 */
|
||||||
static int copy_via_headers(struct sip_pvt *p, struct sip_request *req, struct sip_request *orig, char *field)
|
static int copy_via_headers(struct sip_pvt *p, struct sip_request *req, struct sip_request *orig, char *field)
|
||||||
{
|
{
|
||||||
char tmp[256], *oh, *end;
|
char tmp[256], *oh, *end;
|
||||||
int start = 0;
|
int start = 0;
|
||||||
int copied = 0;
|
int copied = 0;
|
||||||
char new[256];
|
|
||||||
char iabuf[INET_ADDRSTRLEN];
|
char iabuf[INET_ADDRSTRLEN];
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
oh = __get_header(orig, field, &start);
|
oh = __get_header(orig, field, &start);
|
||||||
if (!ast_strlen_zero(oh)) {
|
if (!ast_strlen_zero(oh)) {
|
||||||
/* Strip ;rport */
|
if (!copied) { /* Only check for empty rport in topmost via header */
|
||||||
ast_copy_string(tmp, oh, sizeof(tmp));
|
char *rport;
|
||||||
oh = strstr(tmp, ";rport");
|
char new[256];
|
||||||
if (oh) {
|
|
||||||
end = strchr(oh + 1, ';');
|
/* Find ;rport; (empty request) */
|
||||||
if (end)
|
rport = strstr(oh, ";rport");
|
||||||
memmove(oh, end, strlen(end) + 1);
|
if (rport && *(rport+6) == '=')
|
||||||
else
|
rport = NULL; /* We already have a parameter to rport */
|
||||||
*oh = '\0';
|
|
||||||
}
|
if (rport && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) {
|
||||||
if (!copied && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) {
|
/* We need to add received port - rport */
|
||||||
/* Whoo hoo! Now we can indicate port address translation too! Just
|
ast_copy_string(tmp, oh, sizeof(tmp));
|
||||||
another RFC (RFC3581). I'll leave the original comments in for
|
|
||||||
posterity. */
|
rport = strstr(tmp, ";rport");
|
||||||
snprintf(new, sizeof(new), "%s;received=%s;rport=%d", tmp, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
|
|
||||||
|
if (rport) {
|
||||||
|
end = strchr(rport + 1, ';');
|
||||||
|
if (end)
|
||||||
|
memmove(rport, end, strlen(end) + 1);
|
||||||
|
else
|
||||||
|
*rport = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add rport to first VIA header if requested */
|
||||||
|
/* Whoo hoo! Now we can indicate port address translation too! Just
|
||||||
|
another RFC (RFC3581). I'll leave the original comments in for
|
||||||
|
posterity. */
|
||||||
|
snprintf(new, sizeof(new), "%s;received=%s;rport=%d", tmp, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
|
||||||
|
} else {
|
||||||
|
/* We should *always* add a received to the topmost via */
|
||||||
|
snprintf(new, sizeof(new), "%s;received=%s", oh, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr));
|
||||||
|
}
|
||||||
add_header(req, field, new);
|
add_header(req, field, new);
|
||||||
} else {
|
} else {
|
||||||
/* Add what we're responding to */
|
/* Add the following via headers untouched */
|
||||||
add_header(req, field, tmp);
|
add_header(req, field, oh);
|
||||||
}
|
}
|
||||||
copied++;
|
copied++;
|
||||||
} else
|
} else
|
||||||
|
|||||||
Reference in New Issue
Block a user