#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 , } |
Definition in file netsock2.c.
static void __init_ast_sockaddr_stringify_buf | ( | void | ) | [static] |
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.
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.
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().
int ast_connect | ( | int | sockfd, | |
const struct ast_sockaddr * | addr | |||
) |
Wrapper around connect(2) that uses struct ast_sockaddr.
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().
int ast_getsockname | ( | int | sockfd, | |
struct ast_sockaddr * | addr | |||
) |
Wrapper around getsockname(2) that uses struct ast_sockaddr.
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.
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.
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.
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. |
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.
-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.
-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.
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.
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.
addr | The IPv4-mapped address to convert | |
mapped_addr | The resulting IPv4 address |
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.
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.
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.
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.
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.
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.
[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. |
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.
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
[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. |
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.
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. |
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.
This function is thread-safe. The returned string is on static thread-specific storage.
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 |
(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 }
struct ast_threadstorage ast_sockaddr_stringify_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ast_sockaddr_stringify_buf , .custom_init = NULL , } [static] |