34 #include "asterisk/config.h"
41 const struct sockaddr_in6 *sin6;
42 struct sockaddr_in sin4;
52 sin6 = (
const struct sockaddr_in6*)&addr->
ss;
54 memset(&sin4, 0,
sizeof(sin4));
55 sin4.sin_family = AF_INET;
56 sin4.sin_port = sin6->sin6_port;
57 sin4.sin_addr.s_addr = ((uint32_t *)&sin6->sin6_addr)[3];
71 char host[NI_MAXHOST];
72 char port[NI_MAXSERV];
75 static const size_t size =
sizeof(host) - 1 +
sizeof(port) - 1 + 4;
92 if ((e = getnameinfo((
struct sockaddr *)&sa_tmp->
ss, sa_tmp->
len,
97 NI_NUMERICHOST | NI_NUMERICSERV))) {
112 "[%s]:%s" :
"%s:%s", host, port);
119 sa_tmp->
ss.ss_family == AF_INET6 ?
"[%s]" :
"%s", host);
135 char *orig_str =
str;
136 char *host_end = NULL;
138 ast_debug(5,
"Splitting '%s' into...\n", str);
143 for (; *s && *s !=
']'; ++s) {
192 ast_debug(5,
"...host '%s' and port '%s'.\n", *host, *port ? *port :
"");
200 struct addrinfo hints;
201 struct addrinfo *res;
212 memset(&hints, 0,
sizeof(hints));
214 hints.ai_socktype = SOCK_DGRAM;
216 #ifdef AI_NUMERICSERV
217 hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
219 hints.ai_flags = AI_NUMERICHOST;
221 if ((e = getaddrinfo(host, port, &hints, &res))) {
222 if (e != EAI_NONAME) {
224 host,
S_OR(port,
"(null)"), gai_strerror(e));
233 if (res->ai_next != NULL) {
235 "addresses. Ignoring all but the first.\n");
239 addr->
len = res->ai_addrlen;
240 memcpy(&addr->
ss, res->ai_addr, addr->
len);
249 int flags,
int family)
251 struct addrinfo hints, *res, *ai;
252 char *s, *host, *port;
264 memset(&hints, 0,
sizeof(hints));
265 hints.ai_family = family;
266 hints.ai_socktype = SOCK_DGRAM;
268 if ((e = getaddrinfo(host, port, &hints, &res))) {
270 host,
S_OR(port,
"(null)"), gai_strerror(e));
275 for (ai = res; ai; ai = ai->ai_next) {
289 for (ai = res; ai; ai = ai->ai_next) {
290 (*addrs)[i].len = ai->ai_addrlen;
291 memcpy(&(*addrs)[i].ss, ai->ai_addr, ai->ai_addrlen);
308 if (a_tmp->len != b_tmp->
len) {
310 a_tmp = &ipv4_mapped;
312 b_tmp = &ipv4_mapped;
316 if (a_tmp->len < b_tmp->
len) {
318 }
else if (a_tmp->len > b_tmp->
len) {
322 return memcmp(&a_tmp->ss, &b_tmp->
ss, a_tmp->len);
329 const struct in_addr *ip4a, *ip4b;
330 const struct in6_addr *ip6a, *ip6b;
336 if (a_tmp->
len != b_tmp->
len) {
338 a_tmp = &ipv4_mapped;
340 b_tmp = &ipv4_mapped;
346 }
else if (a->
len > b->
len) {
350 switch (a_tmp->
ss.ss_family) {
352 ip4a = &((
const struct sockaddr_in*)&a_tmp->
ss)->sin_addr;
353 ip4b = &((
const struct sockaddr_in*)&b_tmp->
ss)->sin_addr;
354 ret = memcmp(ip4a, ip4b,
sizeof(*ip4a));
357 ip6a = &((
const struct sockaddr_in6*)&a_tmp->
ss)->sin6_addr;
358 ip6b = &((
const struct sockaddr_in6*)&b_tmp->
ss)->sin6_addr;
359 ret = memcmp(ip6a, ip6b,
sizeof(*ip6a));
367 if (addr->
ss.ss_family == AF_INET &&
368 addr->
len ==
sizeof(
struct sockaddr_in)) {
369 return ntohs(((
struct sockaddr_in *)&addr->
ss)->sin_port);
370 }
else if (addr->
ss.ss_family == AF_INET6 &&
371 addr->
len ==
sizeof(
struct sockaddr_in6)) {
372 return ntohs(((
struct sockaddr_in6 *)&addr->
ss)->sin6_port);
375 ast_log(
__LOG_DEBUG, file, line, func,
"Not an IPv4 nor IPv6 address, cannot get port.\n");
382 if (addr->
ss.ss_family == AF_INET &&
383 addr->
len ==
sizeof(
struct sockaddr_in)) {
384 ((
struct sockaddr_in *)&addr->
ss)->sin_port = htons(port);
385 }
else if (addr->
ss.ss_family == AF_INET6 &&
386 addr->
len ==
sizeof(
struct sockaddr_in6)) {
387 ((
struct sockaddr_in6 *)&addr->
ss)->sin6_port = htons(port);
390 "Not an IPv4 nor IPv6 address, cannot set port.\n");
396 const struct sockaddr_in *sin = (
struct sockaddr_in *)&addr->
ss;
397 return ntohl(sin->sin_addr.s_addr);
402 return addr->
ss.ss_family == AF_INET &&
403 addr->
len ==
sizeof(
struct sockaddr_in);
408 const struct sockaddr_in6 *sin6 = (
struct sockaddr_in6 *)&addr->
ss;
409 return addr->
len && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr);
414 const struct sockaddr_in6 *sin6 = (
struct sockaddr_in6 *)&addr->
ss;
420 return addr->
ss.ss_family == AF_INET6 &&
421 addr->
len ==
sizeof(
struct sockaddr_in6);
427 struct sockaddr_storage ss;
428 struct sockaddr_in sin;
429 struct sockaddr_in6 sin6;
444 switch (addr->
ss.ss_family) {
446 return ((
const struct sockaddr_in *)&addr->
ss)->sin_addr.s_addr;
448 return ((uint32_t *)&((
const struct sockaddr_in6 *)&addr->
ss)->sin6_addr)[3];
458 addr->
len =
sizeof(addr->
ss);
459 return accept(sockfd, (
struct sockaddr *)&addr->
ss, &addr->
len);
464 return bind(sockfd, (
const struct sockaddr *)&addr->
ss, addr->
len);
469 return connect(sockfd, (
const struct sockaddr *)&addr->
ss, addr->
len);
474 addr->
len =
sizeof(addr->
ss);
475 return getsockname(sockfd, (
struct sockaddr *)&addr->
ss, &addr->
len);
481 src_addr->
len =
sizeof(src_addr->
ss);
482 return recvfrom(sockfd, buf, len, flags,
483 (
struct sockaddr *)&src_addr->
ss, &src_addr->
len);
489 return sendto(sockfd, buf, len, flags,
490 (
const struct sockaddr *)&dest_addr->
ss, dest_addr->
len);
507 if ((res = setsockopt(sockfd, IPPROTO_IP, IP_TOS, &tos,
sizeof(tos)))) {
509 "root privileges): %s\n", desc, tos, strerror(
errno));
511 ast_verb(2,
"Using %s TOS bits %d\n", desc, tos);
515 #if defined(IPV6_TCLASS) && defined(IPPROTO_IPV6)
518 if ((res = setsockopt(sockfd, IPPROTO_IPV6, IPV6_TCLASS, &tos,
sizeof(tos)))) {
520 "root privileges): %s\n", desc, tos, strerror(
errno));
522 ast_verb(2,
"Using %s TOS bits %d in TCLASS field.\n", desc, tos);
529 if (setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &cos,
sizeof(cos))) {
533 ast_verb(2,
"Using %s CoS mark %d\n", desc, cos);
541 struct sockaddr_in *sin,
const char *file,
int line,
const char *func)
544 memset(sin, 0,
sizeof(*sin));
548 if (addr->
len !=
sizeof(*sin)) {
557 *sin = *(
struct sockaddr_in *)&addr->
ss;
562 const char *file,
int line,
const char *func)
564 memcpy(&addr->
ss, sin,
sizeof(*sin));
570 addr->
len =
sizeof(*sin);
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
struct sockaddr_storage ss
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.
Asterisk main include file. File version handling, generic pbx functions.
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
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.
uint32_t ast_sockaddr_ipv4(const struct ast_sockaddr *addr)
Get an IPv4 address of an ast_sockaddr.
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definitions to aid in the use of thread local storage.
Socket address structure.
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
#define ast_verb(level,...)
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
#define AST_SOCKADDR_STR_DEFAULT
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
int _ast_sockaddr_to_sin(const struct ast_sockaddr *addr, struct sockaddr_in *sin, const char *file, int line, const char *func)
#define ast_debug(level,...)
Log a DEBUG message.
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
Splits a string into its host and port components.
int ast_accept(int sockfd, struct ast_sockaddr *addr)
Wrapper around accept(2) that uses struct ast_sockaddr.
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
int ast_sockaddr_hash(const struct ast_sockaddr *addr)
Computes a hash value from the address. The port is ignored.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define AST_SOCKADDR_STR_PORT
int ast_sockaddr_is_ipv6_link_local(const struct ast_sockaddr *addr)
Determine if this is a link-local IPv6 address.
uint16_t _ast_sockaddr_port(const struct ast_sockaddr *addr, const char *file, int line, const char *func)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
#define AST_SOCKADDR_STR_HOST
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
char * ast_sockaddr_stringify_fmt(const struct ast_sockaddr *addr, int format)
Convert a socket address to a string.
void _ast_sockaddr_set_port(struct ast_sockaddr *addr, uint16_t port, const char *file, int line, const char *func)
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
static void * cleanup(void *unused)
void _ast_sockaddr_from_sin(struct ast_sockaddr *addr, const struct sockaddr_in *sin, const char *file, int line, const char *func)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
#define AST_SOCKADDR_STR_ADDR
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
int ast_getsockname(int sockfd, struct ast_sockaddr *addr)
Wrapper around getsockname(2) that uses struct ast_sockaddr.
#define AST_SOCKADDR_STR_FORMAT_MASK
static snd_pcm_format_t format
static struct ast_threadstorage ast_sockaddr_stringify_buf
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
int ast_connect(int sockfd, const struct ast_sockaddr *addr)
Wrapper around connect(2) that uses struct ast_sockaddr.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
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.
#define AST_SOCKADDR_STR_REMOTE