Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 137846) +++ channels/chan_sip.c (working copy) @@ -8079,8 +8079,7 @@ return TRUE; } -/*! \brief Change the other partys IP address based on given contact */ -static int set_address_from_contact(struct sip_pvt *pvt) +static int __set_address_from_contact(const char *fullcontact, struct sockaddr_in *sin) { struct hostent *hp; struct ast_hostent ahp; @@ -8089,15 +8088,8 @@ char contact_buf[256]; char *contact; - if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { - /* NAT: Don't trust the contact field. Just use what they came to us - with. */ - pvt->sa = pvt->recv; - return 0; - } - /* Work on a copy */ - ast_copy_string(contact_buf, pvt->fullcontact, sizeof(contact_buf)); + ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); contact = contact_buf; /* Make sure it's a SIP URL */ @@ -8134,14 +8126,27 @@ ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); return -1; } - pvt->sa.sin_family = AF_INET; - memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); - pvt->sa.sin_port = htons(port); + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); + sin->sin_port = htons(port); return 0; } +/*! \brief Change the other partys IP address based on given contact */ +static int set_address_from_contact(struct sip_pvt *pvt) +{ + if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { + /* NAT: Don't trust the contact field. Just use what they came to us + with. */ + pvt->sa = pvt->recv; + return 0; + } + return __set_address_from_contact(pvt->fullcontact, &pvt->sa); +} + + /*! \brief Parse contact header and save registration (peer registration) */ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) { @@ -17220,6 +17225,12 @@ } if (!ast_strlen_zero(fullcontact)) { ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); + /* We have a hostname in the fullcontact, but if we don't have an + * address listed on the entry (or if it's 'dynamic'), then we need to + * parse the entry to obtain the IP address, so a dynamic host can be + * contacted immediately after reload (as opposed to waiting for it to + * register once again). */ + __set_address_from_contact(fullcontact, &peer->addr); } if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) {