Changeset 6045
- Timestamp:
- Jul 26, 2019 9:32:14 AM (4 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/include/pj/ip_helper.h
r3553 r6045 27 27 28 28 #include <pj/sock.h> 29 #include <pj/string.h> 29 30 30 31 PJ_BEGIN_DECL … … 53 54 } pj_ip_route_entry; 54 55 56 /** 57 * This structure describes options for pj_enum_ip_interface2(). 58 */ 59 typedef struct pj_enum_ip_option 60 { 61 /** 62 * Family of the address to be retrieved. Application may specify 63 * pj_AF_UNSPEC() to retrieve all addresses, or pj_AF_INET() or 64 * pj_AF_INET6() to retrieve interfaces with specific address family. 65 * 66 * Default: pj_AF_UNSPEC(). 67 */ 68 int af; 69 70 /** 71 * IPv6 addresses can have a DEPRECATED flag, if this flag is set, any 72 * DEPRECATED IPv6 address will be omitted. Currently this is only 73 * available for Linux, on other platforms, if this flag is set, 74 * pj_enum_ip_interface2() will return PJ_ENOTSUP. 75 * 76 * Default: PJ_FALSE. 77 */ 78 pj_bool_t omit_deprecated_ipv6; 79 80 } pj_enum_ip_option; 81 82 83 /** 84 * Get default values of IP enumeration option. 85 * 86 * @param opt The IP enumeration option. 87 */ 88 PJ_INLINE(void) pj_enum_ip_option_default(pj_enum_ip_option *opt) 89 { 90 pj_bzero(opt, sizeof(*opt)); 91 } 92 55 93 56 94 /** … … 76 114 77 115 /** 116 * Enumerate the local IP interfaces currently active in the host with 117 * capability to filter DEPRECATED IPv6 addresses (currently only for Linux). 118 * 119 * @param opt The option, default option will be used if NULL. 120 * @param count On input, specify the number of entries. On output, 121 * it will be filled with the actual number of entries. 122 * @param ifs Array of socket (with flags) addresses, which address part 123 * will be filled with the interface address. The address 124 * family part will be initialized with the address 125 * family of the IP address. 126 * 127 * @return PJ_SUCCESS on success, or the appropriate error code. 128 */ 129 PJ_DECL(pj_status_t) pj_enum_ip_interface2(const pj_enum_ip_option *opt, 130 unsigned *count, 131 pj_sockaddr ifs[]); 132 133 /** 78 134 * Enumerate the IP routing table for this host. 79 135 * -
pjproject/trunk/pjlib/src/pj/ip_helper_generic.c
r4355 r6045 26 26 #include <pj/sock.h> 27 27 28 29 #if defined(PJ_LINUX) && PJ_LINUX!=0 30 /* The following headers are used to get DEPRECATED addresses */ 31 #include <arpa/inet.h> 32 #include <asm/types.h> 33 #include <linux/netlink.h> 34 #include <linux/rtnetlink.h> 35 #include <sys/socket.h> 36 #include <unistd.h> 37 #endif 38 28 39 /* Set to 1 to enable tracing */ 29 40 #if 0 … … 408 419 } 409 420 421 static pj_status_t get_ipv6_deprecated(unsigned *count, pj_sockaddr addr[]) 422 { 423 #if defined(PJ_LINUX) && PJ_LINUX!=0 424 struct { 425 struct nlmsghdr nlmsg_info; 426 struct ifaddrmsg ifaddrmsg_info; 427 } netlink_req; 428 429 long pagesize = sysconf(_SC_PAGESIZE); 430 if (!pagesize) 431 pagesize = 4096; /* Assume pagesize is 4096 if sysconf() failed */ 432 433 int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 434 if (fd < 0) 435 return PJ_RETURN_OS_ERROR(pj_get_native_netos_error()); 436 437 bzero(&netlink_req, sizeof(netlink_req)); 438 439 netlink_req.nlmsg_info.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); 440 netlink_req.nlmsg_info.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; 441 netlink_req.nlmsg_info.nlmsg_type = RTM_GETADDR; 442 netlink_req.nlmsg_info.nlmsg_pid = getpid(); 443 netlink_req.ifaddrmsg_info.ifa_family = AF_INET6; 444 445 int rtn = send(fd, &netlink_req, netlink_req.nlmsg_info.nlmsg_len, 0); 446 if (rtn < 0) 447 return PJ_RETURN_OS_ERROR(pj_get_native_netos_error()); 448 449 char read_buffer[pagesize]; 450 size_t idx = 0; 451 452 while(1) { 453 bzero(read_buffer, pagesize); 454 int read_size = recv(fd, read_buffer, pagesize, 0); 455 if (read_size < 0) 456 return PJ_RETURN_OS_ERROR(pj_get_native_netos_error()); 457 458 struct nlmsghdr *nlmsg_ptr = (struct nlmsghdr *) read_buffer; 459 int nlmsg_len = read_size; 460 461 if (nlmsg_len < sizeof (struct nlmsghdr)) 462 return PJ_ETOOSMALL; 463 464 if (nlmsg_ptr->nlmsg_type == NLMSG_DONE) 465 break; 466 467 for(; NLMSG_OK(nlmsg_ptr, nlmsg_len); 468 nlmsg_ptr = NLMSG_NEXT(nlmsg_ptr, nlmsg_len)) 469 { 470 struct ifaddrmsg *ifaddrmsg_ptr; 471 struct rtattr *rtattr_ptr; 472 int ifaddrmsg_len; 473 474 ifaddrmsg_ptr = (struct ifaddrmsg*)NLMSG_DATA(nlmsg_ptr); 475 476 if (ifaddrmsg_ptr->ifa_flags & IFA_F_DEPRECATED || 477 ifaddrmsg_ptr->ifa_flags & IFA_F_TENTATIVE) 478 { 479 rtattr_ptr = (struct rtattr*)IFA_RTA(ifaddrmsg_ptr); 480 ifaddrmsg_len = IFA_PAYLOAD(nlmsg_ptr); 481 482 for(;RTA_OK(rtattr_ptr, ifaddrmsg_len); 483 rtattr_ptr = RTA_NEXT(rtattr_ptr, ifaddrmsg_len)) 484 { 485 switch(rtattr_ptr->rta_type) { 486 case IFA_ADDRESS: 487 // Check if addr can contains more data 488 if (idx >= *count) 489 break; 490 // Store deprecated IP 491 char deprecatedAddr[PJ_INET6_ADDRSTRLEN]; 492 inet_ntop(ifaddrmsg_ptr->ifa_family, 493 RTA_DATA(rtattr_ptr), 494 deprecatedAddr, 495 sizeof(deprecatedAddr)); 496 pj_str_t pj_addr_str; 497 pj_cstr(&pj_addr_str, deprecatedAddr); 498 pj_sockaddr_init(pj_AF_INET6(), &addr[idx], 499 &pj_addr_str, 0); 500 ++idx; 501 default: 502 break; 503 } 504 } 505 } 506 } 507 } 508 509 close(fd); 510 *count = idx; 511 512 return PJ_SUCCESS; 513 #else 514 *count = 0; 515 return PJ_ENOTSUP; 516 #endif 517 } 518 519 520 /* 521 * Enumerate the local IP interface currently active in the host. 522 */ 523 PJ_DEF(pj_status_t) pj_enum_ip_interface2( const pj_enum_ip_option *opt, 524 unsigned *p_cnt, 525 pj_sockaddr ifs[]) 526 { 527 pj_enum_ip_option opt_; 528 529 if (opt) 530 opt_ = *opt; 531 else 532 pj_enum_ip_option_default(&opt_); 533 534 if (opt_.af != pj_AF_INET() && opt_.omit_deprecated_ipv6) { 535 pj_sockaddr addrs[*p_cnt]; 536 pj_sockaddr deprecatedAddrs[*p_cnt]; 537 unsigned deprecatedCount = *p_cnt; 538 unsigned cnt = 0; 539 pj_status_t status; 540 541 status = get_ipv6_deprecated(&deprecatedCount, deprecatedAddrs); 542 if (status != PJ_SUCCESS) 543 return status; 544 545 status = pj_enum_ip_interface(opt_.af, p_cnt, addrs); 546 if (status != PJ_SUCCESS) 547 return status; 548 549 for (int i = 0; i < *p_cnt; ++i) { 550 ifs[cnt++] = addrs[i]; 551 552 if (addrs[i].addr.sa_family != pj_AF_INET6()) 553 continue; 554 555 for (int j = 0; j < deprecatedCount; ++j) { 556 if (pj_sockaddr_cmp(&addrs[i], &deprecatedAddrs[j]) == 0) { 557 cnt--; 558 break; 559 } 560 } 561 } 562 563 *p_cnt = cnt; 564 return *p_cnt ? PJ_SUCCESS : PJ_ENOTFOUND; 565 } 566 567 return pj_enum_ip_interface(opt_.af, p_cnt, ifs); 568 } -
pjproject/trunk/pjlib/src/pj/ip_helper_symbian.cpp
r3553 r6045 139 139 140 140 /* 141 * Enumerate the local IP interface currently active in the host. 142 */ 143 PJ_DEF(pj_status_t) pj_enum_ip_interface2( const pj_enum_ip_option *opt, 144 unsigned *count, 145 pj_sockaddr ifs[]) 146 { 147 pj_enum_ip_option opt_; 148 149 if (opt && opt->omit_deprecated_ipv6) 150 return PJ_ENOTSUP; 151 152 if (opt) 153 opt_ = *opt; 154 else 155 pj_enum_ip_option_default(&opt_); 156 157 return pj_enum_ip_interface(opt_.af, count, ifs); 158 } 159 160 /* 141 161 * Enumerate the IP routing table for this host. 142 162 */ -
pjproject/trunk/pjlib/src/pj/ip_helper_win32.c
r3553 r6045 380 380 } 381 381 382 383 /* 384 * Enumerate the local IP interface currently active in the host. 385 */ 386 PJ_DEF(pj_status_t) pj_enum_ip_interface2( const pj_enum_ip_option *opt, 387 unsigned *p_cnt, 388 pj_sockaddr ifs[]) 389 { 390 pj_enum_ip_option opt_; 391 392 if (opt && opt->omit_deprecated_ipv6) 393 return PJ_ENOTSUP; 394 395 if (opt) 396 opt_ = *opt; 397 else 398 pj_enum_ip_option_default(&opt_); 399 400 return pj_enum_ip_interface(opt_.af, p_cnt, ifs); 401 } 402 403 382 404 /* 383 405 * Enumerate the IP routing table for this host. -
pjproject/trunk/pjlib/src/pj/ip_helper_winphone8.c
r5539 r6045 42 42 43 43 /* 44 * Enumerate the local IP interface currently active in the host. 45 */ 46 PJ_DEF(pj_status_t) pj_enum_ip_interface2( const pj_enum_ip_option *opt, 47 unsigned *p_cnt, 48 pj_sockaddr ifs[]) 49 { 50 PJ_UNUSED_ARG(opt); 51 PJ_UNUSED_ARG(ifs); 52 53 PJ_ASSERT_RETURN(p_cnt, PJ_EINVAL); 54 55 *p_cnt = 0; 56 57 return PJ_ENOTSUP; 58 } 59 60 61 62 63 /* 44 64 * Enumerate the IP routing table for this host. 45 65 */ -
pjproject/trunk/pjnath/src/pjnath/stun_sock.c
r5997 r6045 683 683 } else { 684 684 pj_sockaddr def_addr; 685 pj_uint16_t port = pj_sockaddr_get_port(&info->bound_addr); 685 pj_uint16_t port = pj_sockaddr_get_port(&info->bound_addr); 686 pj_enum_ip_option enum_opt; 686 687 unsigned i; 687 688 … … 698 699 699 700 /* Enum all IP interfaces in the host */ 701 pj_enum_ip_option_default(&enum_opt); 702 enum_opt.af = stun_sock->af; 703 enum_opt.omit_deprecated_ipv6 = PJ_TRUE; 700 704 info->alias_cnt = PJ_ARRAY_SIZE(info->aliases); 701 status = pj_enum_ip_interface(stun_sock->af, &info->alias_cnt, 702 info->aliases); 705 status = pj_enum_ip_interface2(&enum_opt, &info->alias_cnt, 706 info->aliases); 707 if (status == PJ_ENOTSUP) { 708 /* Try again without omitting deprecated IPv6 addresses */ 709 enum_opt.omit_deprecated_ipv6 = PJ_FALSE; 710 status = pj_enum_ip_interface2(&enum_opt, &info->alias_cnt, 711 info->aliases); 712 } 713 703 714 if (status != PJ_SUCCESS) { 704 715 /* If enumeration fails, just return the default address */
Note: See TracChangeset
for help on using the changeset viewer.