Use populate_sockaddr_in_from_name instead of inet_aton: this ensures that c= fields with FQDNs are handled correctly.

git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@744 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Richard Newman 19 years ago
parent d09e9a7bbb
commit 7b3563b882

@ -368,8 +368,12 @@ void AmRtpStream::setRAddr(const string& addr, unsigned short port)
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
if(!inet_aton(addr.c_str(),&sa.sin_addr)){
ERROR("address not valid (host: %s)\n",addr.c_str());
/* inet_aton only supports dot-notation IP address strings... but an RFC
* 4566 unicast-address, as found in c=, can be an FQDN (or other!).
* We need to do more sophisticated parsing -- hence p_s_i_f_n().
*/
if (!populate_sockaddr_in_from_name(addr, &sa)) {
ERROR("Address not valid (host: %s).\n", addr.c_str());
throw string("invalid address");
}

@ -398,6 +398,51 @@ string get_ip_from_name(const string& name)
return get_addr_str(a);
}
/* Takes a string representation of an IP address, or an FQDN,
* and populates the provided struct sockaddr_in (similar to
* inet_aton).
* Returns the hostent for the input, or NULL on failure.
* Almost certainly won't work with IPv6 addresses.
*/
int populate_sockaddr_in_from_name(const string& name, struct sockaddr_in *sa) {
if (NULL == sa) {
return 0;
}
int res = 0;
struct addrinfo hints;
struct addrinfo *result, *rp;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET; // AF_UNSPEC for IPv4 or IPv6
hints.ai_socktype = SOCK_DGRAM; // Datagram socket.
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_protocol = 0; // Any protocol.
int s = getaddrinfo(name.c_str(), NULL, &hints, &result);
if (s != 0) {
WARN("getaddrinfo failed on %s: %s.\n",
name.c_str(),
gai_strerror(s));
return res;
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
if ((rp->ai_addrlen != sizeof(struct sockaddr_in)) || // Should not happen.
(rp->ai_socktype != SOCK_DGRAM) ||
(rp->ai_family != AF_INET)) // TODO: Won't behave with IPv6.
continue;
memcpy(&(sa->sin_addr),
&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
sizeof(sa->sin_addr));
res = 1;
break;
}
freeaddrinfo(result);
return res;
}
string uri_from_name_addr(const string& name_addr)
{
string uri = name_addr;

@ -221,6 +221,14 @@ string get_addr_str(struct in_addr in);
string uri_from_name_addr(const string& name_addr);
string get_ip_from_name(const string& name);
/* Generalized hostname/IP address handling -- wherever you would use
* inet_aton(addr.c_str(), &sa.sin_addr)
* instead use
* populate_sockaddr_in_from_name(addr, &sa)
*/
int populate_sockaddr_in_from_name(const string& name,
struct sockaddr_in *sa);
#ifdef SUPPORT_IPV6
int inet_aton_v6(const char* name, struct sockaddr_storage* ss);
void set_port_v6(struct sockaddr_storage* ss, short port);

Loading…
Cancel
Save