Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 263582) +++ channels/chan_sip.c (working copy) @@ -12304,37 +12304,38 @@ ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); } - /* Check that they're allowed to register at this IP */ - /* 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); - ast_string_field_set(peer, fullcontact, ""); - ast_string_field_set(pvt, our_contact, ""); - return PARSE_REGISTER_FAILED; - } - memcpy(&testsin.sin_addr, hp->h_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; - } - - /*! \todo This could come before the checking of DNS earlier on, to avoid - DNS lookups where we don't need it... */ 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 */ + 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); + 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); } else { /* Don't trust the contact field. Just use what they came to us with */ + ast_debug(1, "Store REGISTER's src-IP:port for call routing.\n"); peer->addr = pvt->recv; } + /* 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 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 */