Asterisk - The Open Source Telephony Project  18.5.0
netsock2.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2010, Digium, Inc.
5  *
6  * Viagénie <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief Network socket handling
22  *
23  * \author Viagénie <[email protected]>
24  */
25 
26 /*** MODULEINFO
27  <support_level>core</support_level>
28  ***/
29 
30 #include "asterisk.h"
31 
32 #include "asterisk/config.h"
33 #include "asterisk/netsock2.h"
34 #include "asterisk/utils.h"
35 #include "asterisk/threadstorage.h"
36 
37 int ast_sockaddr_ipv4_mapped(const struct ast_sockaddr *addr, struct ast_sockaddr *ast_mapped)
38 {
39  const struct sockaddr_in6 *sin6;
40  struct sockaddr_in sin4;
41 
42  if (!ast_sockaddr_is_ipv6(addr)) {
43  return 0;
44  }
45 
46  if (!ast_sockaddr_is_ipv4_mapped(addr)) {
47  return 0;
48  }
49 
50  sin6 = (const struct sockaddr_in6*)&addr->ss;
51 
52  memset(&sin4, 0, sizeof(sin4));
53  sin4.sin_family = AF_INET;
54  sin4.sin_port = sin6->sin6_port;
55  sin4.sin_addr.s_addr = ((uint32_t *)&sin6->sin6_addr)[3];
56 
57  ast_sockaddr_from_sin(ast_mapped, &sin4);
58 
59  return 1;
60 }
61 
62 
64 
65 char *ast_sockaddr_stringify_fmt(const struct ast_sockaddr *sa, int format)
66 {
67  struct ast_sockaddr sa_ipv4;
68  const struct ast_sockaddr *sa_tmp;
69  char host[NI_MAXHOST];
70  char port[NI_MAXSERV];
71  struct ast_str *str;
72  int e;
73  static const size_t size = sizeof(host) - 1 + sizeof(port) - 1 + 4;
74 
75 
76  if (ast_sockaddr_isnull(sa)) {
77  return "(null)";
78  }
79 
80  if (!(str = ast_str_thread_get(&ast_sockaddr_stringify_buf, size))) {
81  return "";
82  }
83 
84  if (ast_sockaddr_ipv4_mapped(sa, &sa_ipv4)) {
85  sa_tmp = &sa_ipv4;
86  } else {
87  sa_tmp = sa;
88  }
89 
90  if ((e = getnameinfo((struct sockaddr *)&sa_tmp->ss, sa_tmp->len,
91  format & AST_SOCKADDR_STR_ADDR ? host : NULL,
92  format & AST_SOCKADDR_STR_ADDR ? sizeof(host) : 0,
93  format & AST_SOCKADDR_STR_PORT ? port : 0,
94  format & AST_SOCKADDR_STR_PORT ? sizeof(port): 0,
95  NI_NUMERICHOST | NI_NUMERICSERV))) {
96  ast_log(LOG_ERROR, "getnameinfo(): %s\n", gai_strerror(e));
97  return "";
98  }
99 
100  if ((format & AST_SOCKADDR_STR_REMOTE) == AST_SOCKADDR_STR_REMOTE) {
101  char *p;
102  if (ast_sockaddr_is_ipv6_link_local(sa) && (p = strchr(host, '%'))) {
103  *p = '\0';
104  }
105  }
106 
107  switch ((format & AST_SOCKADDR_STR_FORMAT_MASK)) {
109  ast_str_set(&str, 0, sa_tmp->ss.ss_family == AF_INET6 ?
110  "[%s]:%s" : "%s:%s", host, port);
111  break;
113  ast_str_set(&str, 0, "%s", host);
114  break;
116  ast_str_set(&str, 0,
117  sa_tmp->ss.ss_family == AF_INET6 ? "[%s]" : "%s", host);
118  break;
120  ast_str_set(&str, 0, "%s", port);
121  break;
122  default:
123  ast_log(LOG_ERROR, "Invalid format\n");
124  return "";
125  }
126 
127  return ast_str_buffer(str);
128 }
129 
131 {
132  struct ast_sockaddr sa_ipv4;
133  const struct ast_sockaddr *sa_tmp;
134  int bits = 0;
135  int bytes;
136  int i;
137  int j;
138  char *addr;
139 
140  if (ast_sockaddr_isnull(sa)) {
141  return 0;
142  }
143 
144  if (ast_sockaddr_ipv4_mapped(sa, &sa_ipv4)) {
145  sa_tmp = &sa_ipv4;
146  } else {
147  sa_tmp = sa;
148  }
149 
150  bytes = sa_tmp->len;
151  addr = ((struct sockaddr *)&sa_tmp->ss)->sa_data;
152 
153  for (i = 0; i < bytes ; ++i) {
154  for (j = 0; j < 8; ++j) {
155  if ((addr[i] >> j) & 1) {
156  bits++;
157  }
158  }
159  }
160 
161  return bits;
162 }
163 
164 int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
165 {
166  char *s = str;
167  char *orig_str = str;/* Original string in case the port presence is incorrect. */
168  char *host_end = NULL;/* Delay terminating the host in case the port presence is incorrect. */
169 
170  ast_debug(5, "Splitting '%s' into...\n", str);
171  *host = NULL;
172  *port = NULL;
173  if (*s == '[') {
174  *host = ++s;
175  for (; *s && *s != ']'; ++s) {
176  }
177  if (*s == ']') {
178  host_end = s;
179  ++s;
180  }
181  if (*s == ':') {
182  *port = s + 1;
183  }
184  } else {
185  *host = s;
186  for (; *s; ++s) {
187  if (*s == ':') {
188  if (*port) {
189  *port = NULL;
190  break;
191  } else {
192  *port = s;
193  }
194  }
195  }
196  if (*port) {
197  host_end = *port;
198  ++*port;
199  }
200  }
201 
202  switch (flags & PARSE_PORT_MASK) {
203  case PARSE_PORT_IGNORE:
204  *port = NULL;
205  break;
206  case PARSE_PORT_REQUIRE:
207  if (*port == NULL) {
208  ast_log(LOG_WARNING, "Port missing in %s\n", orig_str);
209  return 0;
210  }
211  break;
212  case PARSE_PORT_FORBID:
213  if (*port != NULL) {
214  ast_log(LOG_WARNING, "Port disallowed in %s\n", orig_str);
215  return 0;
216  }
217  break;
218  }
219 
220  /* Can terminate the host string now if needed. */
221  if (host_end) {
222  *host_end = '\0';
223  }
224  ast_debug(5, "...host '%s' and port '%s'.\n", *host, *port ? *port : "");
225  return 1;
226 }
227 
228 
229 
230 int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
231 {
232  struct addrinfo hints;
233  struct addrinfo *res;
234  char *s;
235  char *host;
236  char *port;
237  int e;
238 
239  s = ast_strdupa(str);
240  if (!ast_sockaddr_split_hostport(s, &host, &port, flags)) {
241  return 0;
242  }
243 
244  memset(&hints, 0, sizeof(hints));
245  /* Hint to get only one entry from getaddrinfo */
246  hints.ai_socktype = SOCK_DGRAM;
247 
248 #ifdef AI_NUMERICSERV
249  hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
250 #else
251  hints.ai_flags = AI_NUMERICHOST;
252 #endif
253  if ((e = getaddrinfo(host, port, &hints, &res))) {
254  if (e != EAI_NONAME) { /* if this was just a host name rather than a ip address, don't print error */
255  ast_log(LOG_ERROR, "getaddrinfo(\"%s\", \"%s\", ...): %s\n",
256  host, S_OR(port, "(null)"), gai_strerror(e));
257  }
258  return 0;
259  }
260 
261  /*
262  * I don't see how this could be possible since we're not resolving host
263  * names. But let's be careful...
264  */
265  if (res->ai_next != NULL) {
266  ast_log(LOG_WARNING, "getaddrinfo() returned multiple "
267  "addresses. Ignoring all but the first.\n");
268  }
269 
270  if (addr) {
271  addr->len = res->ai_addrlen;
272  memcpy(&addr->ss, res->ai_addr, addr->len);
273  }
274 
275  freeaddrinfo(res);
276 
277  return 1;
278 }
279 
280 int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str,
281  int flags, int family)
282 {
283  struct addrinfo hints, *res, *ai;
284  char *s, *host, *port;
285  int e, i, res_cnt;
286 
287  if (!str) {
288  *addrs = NULL;
289  return 0;
290  }
291 
292  s = ast_strdupa(str);
293  if (!ast_sockaddr_split_hostport(s, &host, &port, flags)) {
294  *addrs = NULL;
295  return 0;
296  }
297 
298  memset(&hints, 0, sizeof(hints));
299  hints.ai_family = family;
300  hints.ai_socktype = SOCK_DGRAM;
301 
302  if ((e = getaddrinfo(host, port, &hints, &res))) {
303  ast_log(LOG_ERROR, "getaddrinfo(\"%s\", \"%s\", ...): %s\n",
304  host, S_OR(port, "(null)"), gai_strerror(e));
305  *addrs = NULL;
306  return 0;
307  }
308 
309  res_cnt = 0;
310  for (ai = res; ai; ai = ai->ai_next) {
311  res_cnt++;
312  }
313 
314  if (res_cnt == 0) {
315  *addrs = NULL;
316  goto cleanup;
317  }
318 
319  if ((*addrs = ast_malloc(res_cnt * sizeof(struct ast_sockaddr))) == NULL) {
320  res_cnt = 0;
321  goto cleanup;
322  }
323 
324  i = 0;
325  for (ai = res; ai; ai = ai->ai_next) {
326  (*addrs)[i].len = ai->ai_addrlen;
327  memcpy(&(*addrs)[i].ss, ai->ai_addr, ai->ai_addrlen);
328  ++i;
329  }
330 
331 cleanup:
332  freeaddrinfo(res);
333  return res_cnt;
334 }
335 
336 /*! \brief Pulls first resolved address and returns it */
338  const char* name, int flag, int family)
339 {
340  struct ast_sockaddr *addrs;
341  int addrs_cnt;
342 
343  addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family);
344  if (addrs_cnt <= 0) {
345  return 1;
346  }
347  if (addrs_cnt > 1) {
348  ast_debug(1, "Multiple addresses resolving %s, using the first one only\n", name);
349  }
350 
351  ast_sockaddr_copy(addr, &addrs[0]);
352 
353  ast_free(addrs);
354  return 0;
355 }
356 
357 int ast_sockaddr_apply_netmask(const struct ast_sockaddr *addr, const struct ast_sockaddr *netmask,
358  struct ast_sockaddr *result)
359 {
360  int res = 0;
361 
362  if (ast_sockaddr_is_ipv4(addr)) {
363  struct sockaddr_in result4 = { 0, };
364  struct sockaddr_in *addr4 = (struct sockaddr_in *) &addr->ss;
365  struct sockaddr_in *mask4 = (struct sockaddr_in *) &netmask->ss;
366  result4.sin_family = AF_INET;
367  result4.sin_addr.s_addr = addr4->sin_addr.s_addr & mask4->sin_addr.s_addr;
368  ast_sockaddr_from_sin(result, &result4);
369  } else if (ast_sockaddr_is_ipv6(addr)) {
370  struct sockaddr_in6 result6 = { 0, };
371  struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &addr->ss;
372  struct sockaddr_in6 *mask6 = (struct sockaddr_in6 *) &netmask->ss;
373  int i;
374  result6.sin6_family = AF_INET6;
375  for (i = 0; i < 4; ++i) {
376  V6_WORD(&result6, i) = V6_WORD(addr6, i) & V6_WORD(mask6, i);
377  }
378  memcpy(&result->ss, &result6, sizeof(result6));
379  result->len = sizeof(result6);
380  } else {
381  /* Unsupported address scheme */
382  res = -1;
383  }
384 
385  return res;
386 }
387 
388 int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
389 {
390  const struct ast_sockaddr *a_tmp, *b_tmp;
391  struct ast_sockaddr ipv4_mapped;
392 
393  a_tmp = a;
394  b_tmp = b;
395 
396  if (a_tmp->len != b_tmp->len) {
397  if (ast_sockaddr_ipv4_mapped(a, &ipv4_mapped)) {
398  a_tmp = &ipv4_mapped;
399  } else if (ast_sockaddr_ipv4_mapped(b, &ipv4_mapped)) {
400  b_tmp = &ipv4_mapped;
401  }
402  }
403 
404  if (a_tmp->len < b_tmp->len) {
405  return -1;
406  } else if (a_tmp->len > b_tmp->len) {
407  return 1;
408  }
409 
410  return memcmp(&a_tmp->ss, &b_tmp->ss, a_tmp->len);
411 }
412 
413 int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
414 {
415  const struct ast_sockaddr *a_tmp, *b_tmp;
416  struct ast_sockaddr ipv4_mapped;
417  const struct in_addr *ip4a, *ip4b;
418  const struct in6_addr *ip6a, *ip6b;
419  int ret = -1;
420 
421  a_tmp = a;
422  b_tmp = b;
423 
424  if (a_tmp->len != b_tmp->len) {
425  if (ast_sockaddr_ipv4_mapped(a, &ipv4_mapped)) {
426  a_tmp = &ipv4_mapped;
427  } else if (ast_sockaddr_ipv4_mapped(b, &ipv4_mapped)) {
428  b_tmp = &ipv4_mapped;
429  }
430  }
431 
432  if (a->len < b->len) {
433  ret = -1;
434  } else if (a->len > b->len) {
435  ret = 1;
436  }
437 
438  switch (a_tmp->ss.ss_family) {
439  case AF_INET:
440  ip4a = &((const struct sockaddr_in*)&a_tmp->ss)->sin_addr;
441  ip4b = &((const struct sockaddr_in*)&b_tmp->ss)->sin_addr;
442  ret = memcmp(ip4a, ip4b, sizeof(*ip4a));
443  break;
444  case AF_INET6:
445  ip6a = &((const struct sockaddr_in6*)&a_tmp->ss)->sin6_addr;
446  ip6b = &((const struct sockaddr_in6*)&b_tmp->ss)->sin6_addr;
447  ret = memcmp(ip6a, ip6b, sizeof(*ip6a));
448  break;
449  }
450  return ret;
451 }
452 
453 uint16_t _ast_sockaddr_port(const struct ast_sockaddr *addr, const char *file, int line, const char *func)
454 {
455  /*
456  * Test addr->len first to be tolerant of an ast_sockaddr_setnull()
457  * addr. In that case addr->len might be the only value initialized.
458  */
459  if (addr->len == sizeof(struct sockaddr_in)
460  && addr->ss.ss_family == AF_INET) {
461  return ntohs(((struct sockaddr_in *)&addr->ss)->sin_port);
462  }
463  if (addr->len == sizeof(struct sockaddr_in6)
464  && addr->ss.ss_family == AF_INET6) {
465  return ntohs(((struct sockaddr_in6 *)&addr->ss)->sin6_port);
466  }
467  if (DEBUG_ATLEAST(1)) {
468  ast_log(__LOG_DEBUG, file, line, func, "Not an IPv4 nor IPv6 address, cannot get port.\n");
469  }
470  return 0;
471 }
472 
473 void _ast_sockaddr_set_port(struct ast_sockaddr *addr, uint16_t port, const char *file, int line, const char *func)
474 {
475  /*
476  * Test addr->len first to be tolerant of an ast_sockaddr_setnull()
477  * addr. In that case addr->len might be the only value initialized.
478  */
479  if (addr->len == sizeof(struct sockaddr_in)
480  && addr->ss.ss_family == AF_INET) {
481  ((struct sockaddr_in *)&addr->ss)->sin_port = htons(port);
482  } else if (addr->len == sizeof(struct sockaddr_in6)
483  && addr->ss.ss_family == AF_INET6) {
484  ((struct sockaddr_in6 *)&addr->ss)->sin6_port = htons(port);
485  } else if (DEBUG_ATLEAST(1)) {
486  ast_log(__LOG_DEBUG, file, line, func,
487  "Not an IPv4 nor IPv6 address, cannot set port.\n");
488  }
489 }
490 
491 uint32_t ast_sockaddr_ipv4(const struct ast_sockaddr *addr)
492 {
493  const struct sockaddr_in *sin = (struct sockaddr_in *)&addr->ss;
494  return ntohl(sin->sin_addr.s_addr);
495 }
496 
497 int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
498 {
499  /*
500  * Test addr->len first to be tolerant of an ast_sockaddr_setnull()
501  * addr. In that case addr->len might be the only value initialized.
502  */
503  return addr->len == sizeof(struct sockaddr_in)
504  && addr->ss.ss_family == AF_INET;
505 }
506 
508 {
509  const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr->ss;
510  return addr->len && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr);
511 }
512 
514 {
515  return ((ast_sockaddr_ipv4(addr) & 0xf0000000) == 0xe0000000);
516 }
517 
519 {
520  const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr->ss;
521  return ast_sockaddr_is_ipv6(addr) && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr);
522 }
523 
524 int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
525 {
526  /*
527  * Test addr->len first to be tolerant of an ast_sockaddr_setnull()
528  * addr. In that case addr->len might be the only value initialized.
529  */
530  return addr->len == sizeof(struct sockaddr_in6)
531  && addr->ss.ss_family == AF_INET6;
532 }
533 
534 int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
535 {
536  union {
537  struct sockaddr_storage ss;
538  struct sockaddr_in sin;
539  struct sockaddr_in6 sin6;
540  } tmp_addr = {
541  .ss = addr->ss,
542  };
543 
544  return (ast_sockaddr_is_ipv4(addr) && (tmp_addr.sin.sin_addr.s_addr == INADDR_ANY)) ||
545  (ast_sockaddr_is_ipv6(addr) && IN6_IS_ADDR_UNSPECIFIED(&tmp_addr.sin6.sin6_addr));
546 }
547 
548 int ast_sockaddr_hash(const struct ast_sockaddr *addr)
549 {
550  /*
551  * For IPv4, return the IP address as-is. For IPv6, return the last 32
552  * bits.
553  */
554  switch (addr->ss.ss_family) {
555  case AF_INET:
556  return ((const struct sockaddr_in *)&addr->ss)->sin_addr.s_addr;
557  case AF_INET6:
558  return ((uint32_t *)&((const struct sockaddr_in6 *)&addr->ss)->sin6_addr)[3];
559  default:
560  ast_log(LOG_ERROR, "Unknown address family '%d'.\n",
561  addr->ss.ss_family);
562  return 0;
563  }
564 }
565 
566 const char *ast_transport2str(enum ast_transport transport)
567 {
568  switch (transport) {
569  case AST_TRANSPORT_TLS:
570  return "TLS";
571  case AST_TRANSPORT_UDP:
572  return "UDP";
573  case AST_TRANSPORT_TCP:
574  return "TCP";
575  case AST_TRANSPORT_WS:
576  return "WS";
577  case AST_TRANSPORT_WSS:
578  return "WSS";
579  }
580 
581  return "Undefined";
582 }
583 
584 int ast_accept(int sockfd, struct ast_sockaddr *addr)
585 {
586  addr->len = sizeof(addr->ss);
587  return accept(sockfd, (struct sockaddr *)&addr->ss, &addr->len);
588 }
589 
590 int ast_bind(int sockfd, const struct ast_sockaddr *addr)
591 {
592  return bind(sockfd, (const struct sockaddr *)&addr->ss, addr->len);
593 }
594 
595 int ast_connect(int sockfd, const struct ast_sockaddr *addr)
596 {
597  return connect(sockfd, (const struct sockaddr *)&addr->ss, addr->len);
598 }
599 
600 int ast_getsockname(int sockfd, struct ast_sockaddr *addr)
601 {
602  addr->len = sizeof(addr->ss);
603  return getsockname(sockfd, (struct sockaddr *)&addr->ss, &addr->len);
604 }
605 
606 ssize_t ast_recvfrom(int sockfd, void *buf, size_t len, int flags,
607  struct ast_sockaddr *src_addr)
608 {
609  src_addr->len = sizeof(src_addr->ss);
610  return recvfrom(sockfd, buf, len, flags,
611  (struct sockaddr *)&src_addr->ss, &src_addr->len);
612 }
613 
614 ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags,
615  const struct ast_sockaddr *dest_addr)
616 {
617  return sendto(sockfd, buf, len, flags,
618  (const struct sockaddr *)&dest_addr->ss, dest_addr->len);
619 }
620 
621 int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
622 {
623  int res = 0;
624  int set_tos;
625  int set_tclass;
626  struct ast_sockaddr addr;
627 
628  /* If the sock address is IPv6, the TCLASS field must be set. */
629  set_tclass = !ast_getsockname(sockfd, &addr) && ast_sockaddr_is_ipv6(&addr) ? 1 : 0;
630 
631  /* If the sock address is IPv4 or (IPv6 set to any address [::]) set TOS bits */
632  set_tos = (!set_tclass || (set_tclass && ast_sockaddr_is_any(&addr))) ? 1 : 0;
633 
634  if (set_tos) {
635  if ((res = setsockopt(sockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) {
636  ast_log(LOG_WARNING, "Unable to set %s DSCP TOS value to %d (may be you have no "
637  "root privileges): %s\n", desc, tos, strerror(errno));
638  } else if (tos) {
639  ast_verb(2, "Using %s TOS bits %d\n", desc, tos);
640  }
641  }
642 
643 #if defined(IPV6_TCLASS) && defined(IPPROTO_IPV6)
644  if (set_tclass) {
645  if (!ast_getsockname(sockfd, &addr) && ast_sockaddr_is_ipv6(&addr)) {
646  if ((res = setsockopt(sockfd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)))) {
647  ast_log(LOG_WARNING, "Unable to set %s DSCP TCLASS field to %d (may be you have no "
648  "root privileges): %s\n", desc, tos, strerror(errno));
649  } else if (tos) {
650  ast_verb(2, "Using %s TOS bits %d in TCLASS field.\n", desc, tos);
651  }
652  }
653  }
654 #endif
655 
656 #ifdef linux
657  if (setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &cos, sizeof(cos))) {
658  ast_log(LOG_WARNING, "Unable to set %s CoS to %d: %s\n", desc, cos,
659  strerror(errno));
660  } else if (cos) {
661  ast_verb(2, "Using %s CoS mark %d\n", desc, cos);
662  }
663 #endif
664 
665  return res;
666 }
667 
668 int _ast_sockaddr_to_sin(const struct ast_sockaddr *addr,
669  struct sockaddr_in *sin, const char *file, int line, const char *func)
670 {
671  if (ast_sockaddr_isnull(addr)) {
672  memset(sin, 0, sizeof(*sin));
673  return 1;
674  }
675 
676  if (addr->len != sizeof(*sin)) {
677  ast_log(__LOG_ERROR, file, line, func, "Bad address cast to IPv4\n");
678  return 0;
679  }
680 
681  if (addr->ss.ss_family != AF_INET && DEBUG_ATLEAST(1)) {
682  ast_log(__LOG_DEBUG, file, line, func, "Address family is not AF_INET\n");
683  }
684 
685  *sin = *(struct sockaddr_in *)&addr->ss;
686  return 1;
687 }
688 
689 void _ast_sockaddr_from_sin(struct ast_sockaddr *addr, const struct sockaddr_in *sin,
690  const char *file, int line, const char *func)
691 {
692  memcpy(&addr->ss, sin, sizeof(*sin));
693 
694  if (addr->ss.ss_family != AF_INET && DEBUG_ATLEAST(1)) {
695  ast_log(__LOG_DEBUG, file, line, func, "Address family is not AF_INET\n");
696  }
697 
698  addr->len = sizeof(*sin);
699 }
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Definition: threadstorage.h:84
struct sockaddr_storage ss
Definition: netsock2.h:98
unsigned int cos
Definition: chan_iax2.c:352
Asterisk main include file. File version handling, generic pbx functions.
#define __LOG_DEBUG
Definition: logger.h:240
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.
Definition: netsock2.c:280
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
ast_transport
Definition: netsock2.h:59
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
const char * ast_transport2str(enum ast_transport transport)
Returns a string representation of an ast_transport.
Definition: netsock2.c:566
socklen_t len
Definition: netsock2.h:99
uint32_t ast_sockaddr_ipv4(const struct ast_sockaddr *addr)
Get an IPv4 address of an ast_sockaddr.
Definition: netsock2.c:491
static const char desc[]
Definition: cdr_mysql.c:73
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.
Definition: netsock2.c:37
int ast_sockaddr_is_ipv4_multicast(const struct ast_sockaddr *addr)
Determine if an IPv4 address is a multicast address.
Definition: netsock2.c:513
#define __LOG_ERROR
Definition: logger.h:284
const char * str
Definition: app_jack.c:147
int ast_accept(int sockfd, struct ast_sockaddr *addr)
Wrapper around accept(2) that uses struct ast_sockaddr.
Definition: netsock2.c:584
#define NULL
Definition: resample.c:96
Definitions to aid in the use of thread local storage.
int ast_sockaddr_hash(const struct ast_sockaddr *addr)
Computes a hash value from the address. The port is ignored.
Definition: netsock2.c:548
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
Definition: netsock2.c:507
Socket address structure.
Definition: netsock2.h:97
#define ast_verb(level,...)
Definition: logger.h:463
#define AST_SOCKADDR_STR_DEFAULT
Definition: netsock2.h:207
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
Utility functions.
unsigned int tos
Definition: chan_iax2.c:351
uint16_t _ast_sockaddr_port(const struct ast_sockaddr *addr, const char *file, int line, const char *func)
Definition: netsock2.c:453
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:413
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.
Definition: netsock2.h:127
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
Configuration File Parser.
int ast_sockaddr_apply_netmask(const struct ast_sockaddr *addr, const struct ast_sockaddr *netmask, struct ast_sockaddr *result)
Apply a netmask to an address and store the result in a separate structure.
Definition: netsock2.c:357
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static char host[256]
Definition: muted.c:77
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:782
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: netsock2.c:614
int ast_sockaddr_is_ipv6_link_local(const struct ast_sockaddr *addr)
Determine if this is a link-local IPv6 address.
Definition: netsock2.c:518
int ast_getsockname(int sockfd, struct ast_sockaddr *addr)
Wrapper around getsockname(2) that uses struct ast_sockaddr.
Definition: netsock2.c:600
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
Network socket handling.
int ast_connect(int sockfd, const struct ast_sockaddr *addr)
Wrapper around connect(2) that uses struct ast_sockaddr.
Definition: netsock2.c:595
int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
Splits a string into its host and port components.
Definition: netsock2.c:164
#define LOG_ERROR
Definition: logger.h:285
#define AST_SOCKADDR_STR_PORT
Definition: netsock2.h:203
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void _ast_sockaddr_from_sin(struct ast_sockaddr *addr, const struct sockaddr_in *sin, const char *file, int line, const char *func)
Definition: netsock2.c:689
#define AST_SOCKADDR_STR_HOST
Definition: netsock2.h:206
char * ast_sockaddr_stringify_fmt(const struct ast_sockaddr *sa, int format)
Convert a socket address to a string.
Definition: netsock2.c:65
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
int _ast_sockaddr_to_sin(const struct ast_sockaddr *addr, struct sockaddr_in *sin, const char *file, int line, const char *func)
Definition: netsock2.c:668
long int flag
Definition: f2c.h:83
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
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: netsock2.c:606
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:497
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
int ast_sockaddr_cidr_bits(const struct ast_sockaddr *sa)
Count the 1 bits in a netmask.
Definition: netsock2.c:130
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define AST_SOCKADDR_STR_ADDR
Definition: netsock2.h:202
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534
static PGresult * result
Definition: cel_pgsql.c:88
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
Definition: netsock2.c:621
static struct test_val b
void _ast_sockaddr_set_port(struct ast_sockaddr *addr, uint16_t port, const char *file, int line, const char *func)
Definition: netsock2.c:473
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
#define AST_SOCKADDR_STR_FORMAT_MASK
Definition: netsock2.h:211
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
int ast_sockaddr_resolve_first_af(struct ast_sockaddr *addr, const char *name, int flag, int family)
Pulls first resolved address and returns it.
Definition: netsock2.c:337
#define DEBUG_ATLEAST(level)
Definition: logger.h:441
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:590
static snd_pcm_format_t format
Definition: chan_alsa.c:102
static struct ast_threadstorage ast_sockaddr_stringify_buf
Definition: netsock2.c:63
#define V6_WORD(sin6, index)
Isolate a 32-bit section of an IPv6 address.
Definition: netsock2.h:77
#define AST_SOCKADDR_STR_REMOTE
Definition: netsock2.h:205
static struct test_val a