diff --git a/channels/chan_sip.c b/channels/chan_sip.c index c1113a1cfe..d6bb077e1c 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -12232,6 +12232,22 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of, if (!peer) { peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE); } + + /* If the peer is still not found, try the address and port from the + * contact header. If the transport type is TCP or TLS it is not possible + * to find the peer using p->recv. Because of the way TCP works, the received + * packet's destination port will not match the one the peer table is + * built with. */ + if (!peer && (p->socket.type != SIP_TRANSPORT_UDP)) { + struct sockaddr_in tmpsin; + char contact[SIPBUFSIZE]; + char *tmp; + memcpy(&tmpsin, &p->recv, sizeof(tmpsin)); + ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); + tmp = get_in_brackets(contact); + __set_address_from_contact(tmp, &tmpsin, 1); + peer = find_peer(NULL, &tmpsin, TRUE, FINDPEERS, FALSE); + } } if (!peer) {