| 557 | } |
| 558 | |
| 559 | int anetFdToString(int fd, char *ip, size_t ip_len, int *port, int fd_to_str_type) { |
| 560 | struct sockaddr_storage sa; |
| 561 | socklen_t salen = sizeof(sa); |
| 562 | |
| 563 | if (fd_to_str_type == FD_TO_PEER_NAME) { |
| 564 | if (getpeername(fd, (struct sockaddr *)&sa, &salen) == -1) goto error; |
| 565 | } else { |
| 566 | if (getsockname(fd, (struct sockaddr *)&sa, &salen) == -1) goto error; |
| 567 | } |
| 568 | if (ip_len == 0) goto error; |
| 569 | |
| 570 | if (sa.ss_family == AF_INET) { |
| 571 | struct sockaddr_in *s = (struct sockaddr_in *)&sa; |
| 572 | if (ip) inet_ntop(AF_INET,(void*)&(s->sin_addr),ip,ip_len); |
| 573 | if (port) *port = ntohs(s->sin_port); |
| 574 | } else if (sa.ss_family == AF_INET6) { |
| 575 | struct sockaddr_in6 *s = (struct sockaddr_in6 *)&sa; |
| 576 | if (ip) inet_ntop(AF_INET6,(void*)&(s->sin6_addr),ip,ip_len); |
| 577 | if (port) *port = ntohs(s->sin6_port); |
| 578 | } else if (sa.ss_family == AF_UNIX) { |
| 579 | if (ip) snprintf(ip, ip_len, "/unixsocket"); |
| 580 | if (port) *port = 0; |
| 581 | } else { |
| 582 | goto error; |
| 583 | } |
| 584 | return 0; |
| 585 | |
| 586 | error: |
| 587 | if (ip) { |
| 588 | if (ip_len >= 2) { |
| 589 | ip[0] = '?'; |
| 590 | ip[1] = '\0'; |
| 591 | } else if (ip_len == 1) { |
| 592 | ip[0] = '\0'; |
| 593 | } |
| 594 | } |
| 595 | if (port) *port = 0; |
| 596 | return -1; |
| 597 | } |
| 598 | |
| 599 | /* Format an IP,port pair into something easy to parse. If IP is IPv6 |
| 600 | * (matches for ":"), the ip is surrounded by []. IP and port are just |
no outgoing calls
no test coverage detected