Wed Apr 6 11:30:06 2011

Asterisk developer's documentation


netsock2.c File Reference

Network socket handling. More...

#include "asterisk.h"
#include "asterisk/config.h"
#include "asterisk/netsock2.h"
#include "asterisk/utils.h"
#include "asterisk/threadstorage.h"

Go to the source code of this file.

Functions

static void __init_ast_sockaddr_stringify_buf (void)
void _ast_sockaddr_from_sin (struct ast_sockaddr *addr, const struct sockaddr_in *sin, const char *file, int line, const char *func)
uint16_t _ast_sockaddr_port (const struct ast_sockaddr *addr, const char *file, int line, const char *func)
void _ast_sockaddr_set_port (struct ast_sockaddr *addr, uint16_t port, const char *file, int line, const char *func)
int _ast_sockaddr_to_sin (const struct ast_sockaddr *addr, struct sockaddr_in *sin, const char *file, int line, const char *func)
int ast_accept (int sockfd, struct ast_sockaddr *addr)
 Wrapper around accept(2) that uses struct ast_sockaddr.
int ast_bind (int sockfd, const struct ast_sockaddr *addr)
 Wrapper around bind(2) that uses struct ast_sockaddr.
int ast_connect (int sockfd, const struct ast_sockaddr *addr)
 Wrapper around connect(2) that uses struct ast_sockaddr.
int ast_getsockname (int sockfd, struct ast_sockaddr *addr)
 Wrapper around getsockname(2) that uses struct ast_sockaddr.
ssize_t ast_recvfrom (int sockfd, void *buf, size_t len, int flags, struct ast_sockaddr *src_addr)
 Wrapper around recvfrom(2) that uses struct ast_sockaddr.
ssize_t ast_sendto (int sockfd, const void *buf, size_t len, int flags, const struct ast_sockaddr *dest_addr)
 Wrapper around sendto(2) that uses ast_sockaddr.
int ast_set_qos (int sockfd, int tos, int cos, const char *desc)
 Set type of service.
int ast_sockaddr_cmp (const struct ast_sockaddr *a, const struct ast_sockaddr *b)
 Compares two ast_sockaddr structures.
int ast_sockaddr_cmp_addr (const struct ast_sockaddr *a, const struct ast_sockaddr *b)
 Compares the addresses of two ast_sockaddr structures.
int ast_sockaddr_hash (const struct ast_sockaddr *addr)
 Computes a hash value from the address. The port is ignored.
uint32_t ast_sockaddr_ipv4 (const struct ast_sockaddr *addr)
 Get an IPv4 address of an ast_sockaddr.
int ast_sockaddr_ipv4_mapped (const struct ast_sockaddr *addr, struct ast_sockaddr *ast_mapped)
 Convert an IPv4-mapped IPv6 address into an IPv4 address.
int ast_sockaddr_is_any (const struct ast_sockaddr *addr)
 Determine if the address type is unspecified, or "any" address.
int ast_sockaddr_is_ipv4 (const struct ast_sockaddr *addr)
 Determine if the address is an IPv4 address.
int ast_sockaddr_is_ipv4_mapped (const struct ast_sockaddr *addr)
 Determine if this is an IPv4-mapped IPv6 address.
int ast_sockaddr_is_ipv6 (const struct ast_sockaddr *addr)
 Determine if this is an IPv6 address.
int ast_sockaddr_parse (struct ast_sockaddr *addr, const char *str, int flags)
 Parse an IPv4 or IPv6 address string.
int ast_sockaddr_resolve (struct ast_sockaddr **addrs, const char *str, int flags, int family)
 Parses a string with an IPv4 or IPv6 address and place results into an array.
int ast_sockaddr_split_hostport (char *str, char **host, char **port, int flags)
 Splits a string into its host and port components.
char * ast_sockaddr_stringify_fmt (const struct ast_sockaddr *sa, int format)
 Convert a socket address to a string.

Variables

static struct ast_threadstorage ast_sockaddr_stringify_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ast_sockaddr_stringify_buf , .custom_init = NULL , }


Detailed Description

Network socket handling.

Author:
Viagénie <asteriskv6@viagenie.ca>

Definition in file netsock2.c.


Function Documentation

static void __init_ast_sockaddr_stringify_buf ( void   )  [static]

Definition at line 61 of file netsock2.c.

00064 {

void _ast_sockaddr_from_sin ( struct ast_sockaddr addr,
const struct sockaddr_in *  sin,
const char *  file,
int  line,
const char *  func 
)

Definition at line 527 of file netsock2.c.

References __LOG_DEBUG, ast_log(), ast_sockaddr::len, option_debug, and ast_sockaddr::ss.

00529 {
00530    memcpy(&addr->ss, sin, sizeof(*sin));
00531 
00532    if (addr->ss.ss_family != AF_INET && option_debug >= 1) {
00533       ast_log(__LOG_DEBUG, file, line, func, "Address family is not AF_INET\n");
00534    }
00535 
00536    addr->len = sizeof(*sin);
00537 }

uint16_t _ast_sockaddr_port ( const struct ast_sockaddr addr,
const char *  file,
int  line,
const char *  func 
)

Definition at line 337 of file netsock2.c.

References __LOG_DEBUG, ast_log(), ast_sockaddr::len, option_debug, and ast_sockaddr::ss.

00338 {
00339    if (addr->ss.ss_family == AF_INET &&
00340        addr->len == sizeof(struct sockaddr_in)) {
00341       return ntohs(((struct sockaddr_in *)&addr->ss)->sin_port);
00342    } else if (addr->ss.ss_family == AF_INET6 &&
00343        addr->len == sizeof(struct sockaddr_in6)) {
00344       return ntohs(((struct sockaddr_in6 *)&addr->ss)->sin6_port);
00345    }
00346    if (option_debug >= 1) {
00347       ast_log(__LOG_DEBUG, file, line, func, "Not an IPv4 nor IPv6 address, cannot get port.\n");
00348    }
00349    return 0;
00350 }

void _ast_sockaddr_set_port ( struct ast_sockaddr addr,
uint16_t  port,
const char *  file,
int  line,
const char *  func 
)

Definition at line 352 of file netsock2.c.

References __LOG_DEBUG, ast_log(), ast_sockaddr::len, option_debug, and ast_sockaddr::ss.

00353 {
00354    if (addr->ss.ss_family == AF_INET &&
00355        addr->len == sizeof(struct sockaddr_in)) {
00356       ((struct sockaddr_in *)&addr->ss)->sin_port = htons(port);
00357    } else if (addr->ss.ss_family == AF_INET6 &&
00358        addr->len == sizeof(struct sockaddr_in6)) {
00359       ((struct sockaddr_in6 *)&addr->ss)->sin6_port = htons(port);
00360    } else if (option_debug >= 1) {
00361       ast_log(__LOG_DEBUG, file, line, func,
00362          "Not an IPv4 nor IPv6 address, cannot set port.\n");
00363    }
00364 }

int _ast_sockaddr_to_sin ( const struct ast_sockaddr addr,
struct sockaddr_in *  sin,
const char *  file,
int  line,
const char *  func 
)

Definition at line 506 of file netsock2.c.

References __LOG_DEBUG, __LOG_ERROR, ast_log(), ast_sockaddr_isnull(), ast_sockaddr::len, option_debug, and ast_sockaddr::ss.

00508 {
00509    if (ast_sockaddr_isnull(addr)) {
00510       memset(sin, 0, sizeof(*sin));
00511       return 1;
00512    }
00513 
00514    if (addr->len != sizeof(*sin)) {
00515       ast_log(__LOG_ERROR, file, line, func, "Bad address cast to IPv4\n");
00516       return 0;
00517    }
00518 
00519    if (addr->ss.ss_family != AF_INET && option_debug >= 1) {
00520       ast_log(__LOG_DEBUG, file, line, func, "Address family is not AF_INET\n");
00521    }
00522 
00523    *sin = *(struct sockaddr_in *)&addr->ss;
00524    return 1;
00525 }

int ast_accept ( int  sockfd,
struct ast_sockaddr addr 
)

Wrapper around accept(2) that uses struct ast_sockaddr.

Since:
1.8
For parameter and return information, see the man page for accept(2).

Definition at line 422 of file netsock2.c.

References ast_sockaddr::len, and ast_sockaddr::ss.

Referenced by ast_tcptls_server_root().

00423 {
00424    addr->len = sizeof(addr->ss);
00425    return accept(sockfd, (struct sockaddr *)&addr->ss, &addr->len);
00426 }

int ast_bind ( int  sockfd,
const struct ast_sockaddr addr 
)

Wrapper around bind(2) that uses struct ast_sockaddr.

Since:
1.8
For parameter and return information, see the man page for bind(2).

Definition at line 428 of file netsock2.c.

References ast_sockaddr::len, and ast_sockaddr::ss.

Referenced by ast_rtp_new(), ast_rtp_prop_set(), ast_tcptls_client_create(), ast_tcptls_server_start(), and ast_udptl_new_with_bindaddr().

00429 {
00430    return bind(sockfd, (const struct sockaddr *)&addr->ss, addr->len);
00431 }

int ast_connect ( int  sockfd,
const struct ast_sockaddr addr 
)

Wrapper around connect(2) that uses struct ast_sockaddr.

Since:
1.8
For parameter and return information, see the man page for connect(2).

Definition at line 433 of file netsock2.c.

References ast_sockaddr::len, and ast_sockaddr::ss.

Referenced by ast_ouraddrfor(), ast_tcptls_client_start(), gtalk_update_externip(), and stun_start_monitor().

00434 {
00435    return connect(sockfd, (const struct sockaddr *)&addr->ss, addr->len);
00436 }

int ast_getsockname ( int  sockfd,
struct ast_sockaddr addr 
)

Wrapper around getsockname(2) that uses struct ast_sockaddr.

Since:
1.8
For parameter and return information, see the man page for getsockname(2).

Definition at line 438 of file netsock2.c.

References ast_sockaddr::len, and ast_sockaddr::ss.

Referenced by ast_ouraddrfor(), and ast_set_qos().

00439 {
00440    addr->len = sizeof(addr->ss);
00441    return getsockname(sockfd, (struct sockaddr *)&addr->ss, &addr->len);
00442 }

ssize_t ast_recvfrom ( int  sockfd,
void *  buf,
size_t  len,
int  flags,
struct ast_sockaddr src_addr 
)

Wrapper around recvfrom(2) that uses struct ast_sockaddr.

Since:
1.8
For parameter and return information, see the man page for recvfrom(2).

Definition at line 444 of file netsock2.c.

References ast_sockaddr::len, and ast_sockaddr::ss.

Referenced by __rtp_recvfrom(), ast_udptl_read(), and sipsock_read().

00446 {
00447    src_addr->len = sizeof(src_addr->ss);
00448    return recvfrom(sockfd, buf, len, flags,
00449          (struct sockaddr *)&src_addr->ss, &src_addr->len);
00450 }

ssize_t ast_sendto ( int  sockfd,
const void *  buf,
size_t  len,
int  flags,
const struct ast_sockaddr dest_addr 
)

Wrapper around sendto(2) that uses ast_sockaddr.

Since:
1.8
For parameter and return information, see the man page for sendto(2)

Definition at line 452 of file netsock2.c.

References ast_sockaddr::len, and ast_sockaddr::ss.

Referenced by __rtp_sendto(), __sip_xmit(), ast_udptl_write(), multicast_rtp_write(), and multicast_send_control_packet().

00454 {
00455    return sendto(sockfd, buf, len, flags,
00456             (const struct sockaddr *)&dest_addr->ss, dest_addr->len);
00457 }

int ast_set_qos ( int  sockfd,
int  tos,
int  cos,
const char *  desc 
)

Set type of service.

Since:
1.8
Set ToS ("Type of Service for IPv4 and "Traffic Class for IPv6) and CoS (Linux's SO_PRIORITY)

Parameters:
sockfd File descriptor for socket on which to set the parameters
tos The type of service for the socket
cos The cost of service for the socket
desc A text description of the socket in question.
Return values:
0 Success
-1 Error, with errno set to an appropriate value

Definition at line 459 of file netsock2.c.

References ast_getsockname(), ast_log(), ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_verb, errno, and LOG_WARNING.

Referenced by ast_rtp_qos_set().

00460 {
00461    int res = 0;
00462    int set_tos;
00463    int set_tclass;
00464    struct ast_sockaddr addr;
00465 
00466    /* If the sock address is IPv6, the TCLASS field must be set. */
00467    set_tclass = !ast_getsockname(sockfd, &addr) && ast_sockaddr_is_ipv6(&addr) ? 1 : 0;
00468 
00469    /* If the the sock address is IPv4 or (IPv6 set to any address [::]) set TOS bits */
00470    set_tos = (!set_tclass || (set_tclass && ast_sockaddr_is_any(&addr))) ? 1 : 0;
00471 
00472    if (set_tos) {
00473       if ((res = setsockopt(sockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) {
00474          ast_log(LOG_WARNING, "Unable to set %s DSCP TOS value to %d (may be you have no "
00475             "root privileges): %s\n", desc, tos, strerror(errno));
00476       } else if (tos) {
00477          ast_verb(2, "Using %s TOS bits %d\n", desc, tos);
00478       }
00479    }
00480 
00481 #if defined(IPV6_TCLASS) && defined(IPPROTO_IPV6)
00482    if (set_tclass) {
00483       if (!ast_getsockname(sockfd, &addr) && ast_sockaddr_is_ipv6(&addr)) {
00484          if ((res = setsockopt(sockfd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)))) {
00485             ast_log(LOG_WARNING, "Unable to set %s DSCP TCLASS field to %d (may be you have no "
00486                "root privileges): %s\n", desc, tos, strerror(errno));
00487          } else if (tos) {
00488             ast_verb(2, "Using %s TOS bits %d in TCLASS field.\n", desc, tos);
00489          }
00490       }
00491    }
00492 #endif
00493 
00494 #ifdef linux
00495    if (setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &cos, sizeof(cos))) {
00496       ast_log(LOG_WARNING, "Unable to set %s CoS to %d: %s\n", desc, cos,
00497          strerror(errno));
00498    } else if (cos) {
00499       ast_verb(2, "Using %s CoS mark %d\n", desc, cos);
00500    }
00501 #endif
00502 
00503    return res;
00504 }

int ast_sockaddr_cmp ( const struct ast_sockaddr a,
const struct ast_sockaddr b 
)

Compares two ast_sockaddr structures.

Since:
1.8
Return values:
-1 a is lexicographically smaller than b
0 a is equal to b
1 b is lexicographically smaller than a

Definition at line 272 of file netsock2.c.

References ast_sockaddr_ipv4_mapped(), ast_sockaddr::len, and ast_sockaddr::ss.

Referenced by add_sdp(), ast_rtcp_read(), ast_rtp_instance_get_and_cmp_local_address(), ast_rtp_instance_get_and_cmp_remote_address(), ast_rtp_read(), ast_tcptls_client_create(), ast_tcptls_server_start(), ast_udptl_bridge(), ast_udptl_read(), dnsmgr_refresh(), parse_register_contact(), realtime_peer(), remote_bridge_loop(), rtcp_debug_test_addr(), rtp_debug_test_addr(), sip_debug_test_addr(), threadinfo_locate_cb(), udptl_debug_test_addr(), and update_registry().

00273 {
00274    const struct ast_sockaddr *a_tmp, *b_tmp;
00275    struct ast_sockaddr ipv4_mapped;
00276 
00277    a_tmp = a;
00278    b_tmp = b;
00279 
00280    if (a_tmp->len != b_tmp->len) {
00281       if (ast_sockaddr_ipv4_mapped(a, &ipv4_mapped)) {
00282          a_tmp = &ipv4_mapped;
00283       } else if (ast_sockaddr_ipv4_mapped(b, &ipv4_mapped)) {
00284          b_tmp = &ipv4_mapped;
00285       }
00286    }
00287 
00288    if (a_tmp->len < b_tmp->len) {
00289       return -1;
00290    } else if (a_tmp->len > b_tmp->len) {
00291       return 1;
00292    }
00293 
00294    return memcmp(&a_tmp->ss, &b_tmp->ss, a_tmp->len);
00295 }

int ast_sockaddr_cmp_addr ( const struct ast_sockaddr a,
const struct ast_sockaddr b 
)

Compares the addresses of two ast_sockaddr structures.

Since:
1.8
Return values:
-1 a is lexicographically smaller than b
0 a is equal to b
1 b is lexicographically smaller than a

Definition at line 297 of file netsock2.c.

References ast_sockaddr_ipv4_mapped(), ast_sockaddr::len, and ast_sockaddr::ss.

Referenced by addr_range_cmp_cb(), ast_apply_ha(), get_our_media_address(), peer_ipcmp_cb(), sip_debug_test_addr(), and udptl_debug_test_addr().

00298 {
00299    const struct ast_sockaddr *a_tmp, *b_tmp;
00300    struct ast_sockaddr ipv4_mapped;
00301    const struct in_addr *ip4a, *ip4b;
00302    const struct in6_addr *ip6a, *ip6b;
00303    int ret = -1;
00304 
00305    a_tmp = a;
00306    b_tmp = b;
00307 
00308    if (a_tmp->len != b_tmp->len) {
00309       if (ast_sockaddr_ipv4_mapped(a, &ipv4_mapped)) {
00310          a_tmp = &ipv4_mapped;
00311       } else if (ast_sockaddr_ipv4_mapped(b, &ipv4_mapped)) {
00312          b_tmp = &ipv4_mapped;
00313       }
00314    }
00315 
00316    if (a->len < b->len) {
00317       ret = -1;
00318    } else if (a->len > b->len) {
00319       ret = 1;
00320    }
00321 
00322    switch (a_tmp->ss.ss_family) {
00323    case AF_INET:
00324       ip4a = &((const struct sockaddr_in*)&a_tmp->ss)->sin_addr;
00325       ip4b = &((const struct sockaddr_in*)&b_tmp->ss)->sin_addr;
00326       ret = memcmp(ip4a, ip4b, sizeof(*ip4a));
00327       break;
00328    case AF_INET6:
00329       ip6a = &((const struct sockaddr_in6*)&a_tmp->ss)->sin6_addr;
00330       ip6b = &((const struct sockaddr_in6*)&b_tmp->ss)->sin6_addr;
00331       ret = memcmp(ip6a, ip6b, sizeof(*ip6a));
00332       break;
00333    }
00334    return ret;
00335 }

int ast_sockaddr_hash ( const struct ast_sockaddr addr  ) 

Computes a hash value from the address. The port is ignored.

Since:
1.8
Return values:
0 Unknown address family
other A 32-bit hash derived from the address

Definition at line 404 of file netsock2.c.

References ast_log(), LOG_ERROR, and ast_sockaddr::ss.

Referenced by peer_iphash_cb(), and threadt_hash_cb().

00405 {
00406    /*
00407     * For IPv4, return the IP address as-is. For IPv6, return the last 32
00408     * bits.
00409     */
00410    switch (addr->ss.ss_family) {
00411    case AF_INET:
00412       return ((const struct sockaddr_in *)&addr->ss)->sin_addr.s_addr;
00413    case AF_INET6:
00414       return ((uint32_t *)&((const struct sockaddr_in6 *)&addr->ss)->sin6_addr)[3];
00415    default:
00416       ast_log(LOG_ERROR, "Unknown address family '%d'.\n",
00417          addr->ss.ss_family);
00418       return 0;
00419    }
00420 }

uint32_t ast_sockaddr_ipv4 ( const struct ast_sockaddr addr  ) 

Get an IPv4 address of an ast_sockaddr.

Since:
1.8
Warning:
You should rarely need this function. Only use if you know what you're doing.
Returns:
IPv4 address in network byte order

Definition at line 366 of file netsock2.c.

References ast_sockaddr::ss.

Referenced by iax2_devicestate(), iax2_do_register(), iax2_poke_peer(), jingle_create_candidates(), load_module(), and multicast_send_control_packet().

00367 {
00368    const struct sockaddr_in *sin = (struct sockaddr_in *)&addr->ss;
00369    return ntohl(sin->sin_addr.s_addr);
00370 }

int ast_sockaddr_ipv4_mapped ( const struct ast_sockaddr addr,
struct ast_sockaddr ast_mapped 
)

Convert an IPv4-mapped IPv6 address into an IPv4 address.

Warning:
You should rarely need this function. Only call this if you know what you're doing.
Parameters:
addr The IPv4-mapped address to convert
mapped_addr The resulting IPv4 address
Return values:
0 Unable to make the conversion
1 Successful conversion

Definition at line 35 of file netsock2.c.

References ast_sockaddr_from_sin, ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), and ast_sockaddr::ss.

Referenced by ast_append_ha(), ast_apply_ha(), ast_sockaddr_cmp(), ast_sockaddr_cmp_addr(), and ast_sockaddr_stringify_fmt().

00036 {
00037    const struct sockaddr_in6 *sin6;
00038    struct sockaddr_in sin4;
00039 
00040    if (!ast_sockaddr_is_ipv6(addr)) {
00041       return 0;
00042    }
00043 
00044    if (!ast_sockaddr_is_ipv4_mapped(addr)) {
00045       return 0;
00046    }
00047 
00048    sin6 = (const struct sockaddr_in6*)&addr->ss;
00049 
00050    memset(&sin4, 0, sizeof(sin4));
00051    sin4.sin_family = AF_INET;
00052    sin4.sin_port = sin6->sin6_port;
00053    sin4.sin_addr.s_addr = ((uint32_t *)&sin6->sin6_addr)[3];
00054 
00055    ast_sockaddr_from_sin(ast_mapped, &sin4);
00056 
00057    return 1;
00058 }

int ast_sockaddr_is_any ( const struct ast_sockaddr addr  ) 

Determine if the address type is unspecified, or "any" address.

Since:
1.8
For IPv4, this would be the address 0.0.0.0, and for IPv6, this would be the address ::. The port number is ignored.

Return values:
1 This is an "any" address
0 This is not an "any" address

Definition at line 390 of file netsock2.c.

References ast_sockaddr_is_ipv4(), ast_sockaddr_is_ipv6(), and ast_sockaddr::ss.

Referenced by ast_find_ourip(), ast_set_qos(), ast_sip_ouraddrfor(), get_address_family_filter(), get_our_media_address(), gtalk_get_local_ip(), and sip_show_settings().

00391 {
00392    union {
00393       struct sockaddr_storage ss;
00394       struct sockaddr_in sin;
00395       struct sockaddr_in6 sin6;
00396    } tmp_addr = {
00397       .ss = addr->ss,
00398    };
00399 
00400    return (ast_sockaddr_is_ipv4(addr) && (tmp_addr.sin.sin_addr.s_addr == INADDR_ANY)) ||
00401        (ast_sockaddr_is_ipv6(addr) && IN6_IS_ADDR_UNSPECIFIED(&tmp_addr.sin6.sin6_addr));
00402 }

int ast_sockaddr_is_ipv4 ( const struct ast_sockaddr addr  ) 

Determine if the address is an IPv4 address.

Since:
1.8
Warning:
You should rarely need this function. Only use if you know what you're doing.
Return values:
1 This is an IPv4 address
0 This is an IPv6 or IPv4-mapped IPv6 address

Definition at line 372 of file netsock2.c.

References ast_sockaddr::len, and ast_sockaddr::ss.

Referenced by apply_netmask(), ast_append_ha(), ast_apply_ha(), ast_rtp_new(), ast_rtp_prop_set(), and ast_sockaddr_is_any().

00373 {
00374    return addr->ss.ss_family == AF_INET &&
00375        addr->len == sizeof(struct sockaddr_in);
00376 }

int ast_sockaddr_is_ipv4_mapped ( const struct ast_sockaddr addr  ) 

Determine if this is an IPv4-mapped IPv6 address.

Since:
1.8
Warning:
You should rarely need this function. Only use if you know what you're doing.
Return values:
1 This is an IPv4-mapped IPv6 address.
0 This is not an IPv4-mapped IPv6 address.

Definition at line 378 of file netsock2.c.

References ast_sockaddr::len, and ast_sockaddr::ss.

Referenced by add_sdp(), ast_apply_ha(), ast_rtp_instance_bridge(), and ast_sockaddr_ipv4_mapped().

00379 {
00380    const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr->ss;
00381    return addr->len && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr);
00382 }

int ast_sockaddr_is_ipv6 ( const struct ast_sockaddr addr  ) 

Determine if this is an IPv6 address.

Since:
1.8
Warning:
You should rarely need this function. Only use if you know what you're doing.
Return values:
1 This is an IPv6 or IPv4-mapped IPv6 address.
0 This is an IPv4 address.

Definition at line 384 of file netsock2.c.

References ast_sockaddr::len, and ast_sockaddr::ss.

Referenced by add_sdp(), apply_netmask(), ast_apply_ha(), ast_ouraddrfor(), ast_rtp_new(), ast_rtp_prop_set(), ast_set_qos(), ast_sip_ouraddrfor(), ast_sockaddr_ipv4_mapped(), ast_sockaddr_is_any(), ast_tcptls_client_create(), ast_tcptls_server_start(), ast_udptl_new_with_bindaddr(), get_address_family_filter(), multicast_send_control_packet(), and sip_show_settings().

00385 {
00386    return addr->ss.ss_family == AF_INET6 &&
00387        addr->len == sizeof(struct sockaddr_in6);
00388 }

int ast_sockaddr_parse ( struct ast_sockaddr addr,
const char *  str,
int  flags 
)

Parse an IPv4 or IPv6 address string.

Since:
1.8
Parses a string containing an IPv4 or IPv6 address followed by an optional port (separated by a colon) into a struct ast_sockaddr. The allowed formats are the following:

a.b.c.d a.b.c.d:port a:b:c:...:d [a:b:c:...:d] [a:b:c:...:d]:port

Host names are NOT allowed.

Parameters:
[out] addr The resulting ast_sockaddr
str The string to parse
flags If set to zero, a port MAY be present. If set to PARSE_PORT_IGNORE, a port MAY be present but will be ignored. If set to PARSE_PORT_REQUIRE, a port MUST be present. If set to PARSE_PORT_FORBID, a port MUST NOT be present.
Return values:
1 Success
0 Failure

Definition at line 180 of file netsock2.c.

References ast_log(), ast_sockaddr_split_hostport(), ast_strdupa, ast_sockaddr::len, LOG_ERROR, LOG_WARNING, S_OR, and ast_sockaddr::ss.

Referenced by ast_append_ha(), ast_parse_arg(), build_peer(), multicast_rtp_request(), proxy_update(), reg_source_db(), rtcp_do_debug_ip(), and rtp_do_debug_ip().

00181 {
00182    struct addrinfo hints;
00183    struct addrinfo   *res;
00184    char *s;
00185    char *host;
00186    char *port;
00187    int   e;
00188 
00189    s = ast_strdupa(str);
00190    if (!ast_sockaddr_split_hostport(s, &host, &port, flags)) {
00191       return 0;
00192    }
00193 
00194    memset(&hints, 0, sizeof(hints));
00195    /* Hint to get only one entry from getaddrinfo */
00196    hints.ai_socktype = SOCK_DGRAM;
00197 
00198 #ifdef AI_NUMERICSERV
00199    hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
00200 #else
00201    hints.ai_flags = AI_NUMERICHOST;
00202 #endif
00203    if ((e = getaddrinfo(host, port, &hints, &res))) {
00204       if (e != EAI_NONAME) { /* if this was just a host name rather than a ip address, don't print error */
00205          ast_log(LOG_ERROR, "getaddrinfo(\"%s\", \"%s\", ...): %s\n",
00206             host, S_OR(port, "(null)"), gai_strerror(e));
00207       }
00208       return 0;
00209    }
00210 
00211    /*
00212     * I don't see how this could be possible since we're not resolving host
00213     * names. But let's be careful...
00214     */
00215    if (res->ai_next != NULL) {
00216       ast_log(LOG_WARNING, "getaddrinfo() returned multiple "
00217          "addresses. Ignoring all but the first.\n");
00218    }
00219 
00220    addr->len = res->ai_addrlen;
00221    memcpy(&addr->ss, res->ai_addr, addr->len);
00222 
00223    freeaddrinfo(res);
00224 
00225    return 1;
00226 }

int ast_sockaddr_resolve ( struct ast_sockaddr **  addrs,
const char *  str,
int  flags,
int  family 
)

Parses a string with an IPv4 or IPv6 address and place results into an array.

Since:
1.8
Parses a string containing a host name or an IPv4 or IPv6 address followed by an optional port (separated by a colon). The result is returned into a array of struct ast_sockaddr. Allowed formats for str are the following:

hostname:port host.example.com:port a.b.c.d a.b.c.d:port a:b:c:...:d [a:b:c:...:d] [a:b:c:...:d]:port

Parameters:
[out] addrs The resulting array of ast_sockaddrs
str The string to parse
flags If set to zero, a port MAY be present. If set to PARSE_PORT_IGNORE, a port MAY be present but will be ignored. If set to PARSE_PORT_REQUIRE, a port MUST be present. If set to PARSE_PORT_FORBID, a port MUST NOT be present.
family Only addresses of the given family will be returned. Use 0 or AST_SOCKADDR_UNSPEC to get addresses of all families.
Return values:
0 Failure
non-zero The number of elements in addrs array.

Definition at line 228 of file netsock2.c.

References ast_log(), ast_malloc, ast_sockaddr_split_hostport(), ast_strdupa, cleanup(), len(), LOG_ERROR, and S_OR.

Referenced by ast_sockaddr_resolve_first_af(), gtalk_get_local_ip(), handle_cli_udptl_set_debug(), realtime_peer(), and resolve_first().

00230 {
00231    struct addrinfo hints, *res, *ai;
00232    char *s, *host, *port;
00233    int   e, i, res_cnt;
00234 
00235    s = ast_strdupa(str);
00236    if (!ast_sockaddr_split_hostport(s, &host, &port, flags)) {
00237       return 0;
00238    }
00239 
00240    memset(&hints, 0, sizeof(hints));
00241    hints.ai_family = family;
00242    hints.ai_socktype = SOCK_DGRAM;
00243 
00244    if ((e = getaddrinfo(host, port, &hints, &res))) {
00245       ast_log(LOG_ERROR, "getaddrinfo(\"%s\", \"%s\", ...): %s\n",
00246          host, S_OR(port, "(null)"), gai_strerror(e));
00247       return 0;
00248    }
00249 
00250    res_cnt = 0;
00251    for (ai = res; ai; ai = ai->ai_next) {
00252       res_cnt++;
00253    }
00254 
00255    if ((*addrs = ast_malloc(res_cnt * sizeof(struct ast_sockaddr))) == NULL) {
00256       res_cnt = 0;
00257       goto cleanup;
00258    }
00259 
00260    i = 0;
00261    for (ai = res; ai; ai = ai->ai_next) {
00262       (*addrs)[i].len = ai->ai_addrlen;
00263       memcpy(&(*addrs)[i].ss, ai->ai_addr, ai->ai_addrlen);
00264       ++i;
00265    }
00266 
00267 cleanup:
00268    freeaddrinfo(res);
00269    return res_cnt;
00270 }

int ast_sockaddr_split_hostport ( char *  str,
char **  host,
char **  port,
int  flags 
)

Splits a string into its host and port components.

Since:
1.8
Parameters:
str[in] The string to parse. May be modified by writing a NUL at the end of the host part.
host[out] Pointer to the host component within str.
port[out] Pointer to the port component within str.
flags If set to zero, a port MAY be present. If set to PARSE_PORT_IGNORE, a port MAY be present but will be ignored. If set to PARSE_PORT_REQUIRE, a port MUST be present. If set to PARSE_PORT_FORBID, a port MUST NOT be present.
Return values:
1 Success
0 Failure

Definition at line 121 of file netsock2.c.

References ast_debug, ast_log(), LOG_WARNING, PARSE_PORT_FORBID, PARSE_PORT_IGNORE, PARSE_PORT_MASK, and PARSE_PORT_REQUIRE.

Referenced by ast_sockaddr_parse(), and ast_sockaddr_resolve().

00122 {
00123    char *s = str;
00124 
00125    ast_debug(5, "Splitting '%s' gives...\n", str);
00126    *host = NULL;
00127    *port = NULL;
00128    if (*s == '[') {
00129       *host = ++s;
00130       for (; *s && *s != ']'; ++s) {
00131       }
00132       if (*s == ']') {
00133          *s++ = '\0';
00134       }
00135       if (*s == ':') {
00136          *port = s + 1;
00137       }
00138    } else {
00139       *host = s;
00140       for (; *s; ++s) {
00141          if (*s == ':') {
00142             if (*port) {
00143                *port = NULL;
00144                break;
00145             } else {
00146                *port = s;
00147             }
00148          }
00149       }
00150       if (*port) {
00151          **port = '\0';
00152          ++*port;
00153       }
00154    }
00155    ast_debug(5, "...host '%s' and port '%s'.\n", *host, *port);
00156 
00157    switch (flags & PARSE_PORT_MASK) {
00158    case PARSE_PORT_IGNORE:
00159       *port = NULL;
00160       break;
00161    case PARSE_PORT_REQUIRE:
00162       if (*port == NULL) {
00163          ast_log(LOG_WARNING, "missing port\n");
00164          return 0;
00165       }
00166       break;
00167    case PARSE_PORT_FORBID:
00168       if (*port != NULL) {
00169          ast_log(LOG_WARNING, "port disallowed\n");
00170          return 0;
00171       }
00172       break;
00173    }
00174 
00175    return 1;
00176 }

char* ast_sockaddr_stringify_fmt ( const struct ast_sockaddr addr,
int  format 
)

Convert a socket address to a string.

Since:
1.8
This will be of the form a.b.c.d:xyz for IPv4 and [a:b:c:...:d]:xyz for IPv6.

This function is thread-safe. The returned string is on static thread-specific storage.

Parameters:
addr The input to be stringified
format one of the following: AST_SOCKADDR_STR_DEFAULT: a.b.c.d:xyz for IPv4 [a:b:c:...:d]:xyz for IPv6. AST_SOCKADDR_STR_ADDR: address only a.b.c.d for IPv4 a:b:c:...:d for IPv6. AST_SOCKADDR_STR_HOST: address only, suitable for a URL a.b.c.d for IPv4 [a:b:c:...:d] for IPv6. AST_SOCKADDR_STR_PORT: port only
Return values:
(null) addr is null
"" An error occurred during processing
string The stringified form of the address

Definition at line 63 of file netsock2.c.

References ast_log(), ast_sockaddr_ipv4_mapped(), ast_sockaddr_isnull(), AST_SOCKADDR_STR_ADDR, AST_SOCKADDR_STR_DEFAULT, AST_SOCKADDR_STR_HOST, AST_SOCKADDR_STR_PORT, ast_sockaddr_stringify_buf, ast_str_buffer(), ast_str_set(), ast_str_thread_get(), ast_sockaddr::len, LOG_ERROR, ast_sockaddr::ss, and str.

Referenced by _sip_show_peers(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_host(), and ast_sockaddr_stringify_port().

00064 {
00065    struct ast_sockaddr sa_ipv4;
00066    const struct ast_sockaddr *sa_tmp;
00067    char host[NI_MAXHOST];
00068    char port[NI_MAXSERV];
00069    struct ast_str *str;
00070    int e;
00071    static const size_t size = sizeof(host) - 1 + sizeof(port) - 1 + 4;
00072 
00073 
00074    if (ast_sockaddr_isnull(sa)) {
00075       return "(null)";
00076    }
00077 
00078    if (!(str = ast_str_thread_get(&ast_sockaddr_stringify_buf, size))) {
00079       return "";
00080    }
00081 
00082    if (ast_sockaddr_ipv4_mapped(sa, &sa_ipv4)) {
00083       sa_tmp = &sa_ipv4;
00084    } else {
00085       sa_tmp = sa;
00086    }
00087 
00088    if ((e = getnameinfo((struct sockaddr *)&sa_tmp->ss, sa->len,
00089               format & AST_SOCKADDR_STR_ADDR ? host : NULL,
00090               format & AST_SOCKADDR_STR_ADDR ? sizeof(host) : 0,
00091               format & AST_SOCKADDR_STR_PORT ? port : 0,
00092               format & AST_SOCKADDR_STR_PORT ? sizeof(port): 0,
00093               NI_NUMERICHOST | NI_NUMERICSERV))) {
00094       ast_log(LOG_ERROR, "getnameinfo(): %s\n", gai_strerror(e));
00095       return "";
00096    }
00097 
00098    switch (format)  {
00099    case AST_SOCKADDR_STR_DEFAULT:
00100       ast_str_set(&str, 0, sa_tmp->ss.ss_family == AF_INET6 ?
00101             "[%s]:%s" : "%s:%s", host, port);
00102       break;
00103    case AST_SOCKADDR_STR_ADDR:
00104       ast_str_set(&str, 0, "%s", host);
00105       break;
00106    case AST_SOCKADDR_STR_HOST:
00107       ast_str_set(&str, 0,
00108              sa_tmp->ss.ss_family == AF_INET6 ? "[%s]" : "%s", host);
00109       break;
00110    case AST_SOCKADDR_STR_PORT:
00111       ast_str_set(&str, 0, "%s", port);
00112       break;
00113    default:
00114       ast_log(LOG_ERROR, "Invalid format\n");
00115       return "";
00116    }
00117 
00118    return ast_str_buffer(str);
00119 }


Variable Documentation

struct ast_threadstorage ast_sockaddr_stringify_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ast_sockaddr_stringify_buf , .custom_init = NULL , } [static]

Definition at line 61 of file netsock2.c.

Referenced by ast_sockaddr_stringify_fmt().


Generated on Wed Apr 6 11:30:06 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7