Changeset 3121 for pjproject/trunk
- Timestamp:
- Mar 26, 2010 5:44:04 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/src/pj/sock_common.c
r3107 r3121 691 691 } 692 692 693 static pj_bool_t is_usable_ip(const pj_sockaddr *addr)694 {695 if (addr->addr.sa_family==PJ_AF_INET) {696 /* Only consider if the address is not 127.0.0.0/8 or 0.0.0.0/8.697 * The 0.0.0.0/8 is a special IP class that doesn't seem to be698 * practically useful for our purpose.699 */700 if ((pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127)701 return PJ_FALSE;702 if ((pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==0)703 return PJ_FALSE;704 705 return PJ_TRUE;706 707 } else if (addr->addr.sa_family==PJ_AF_INET6) {708 pj_sockaddr ipv6_loop;709 const pj_str_t loop = { "::1", 3};710 pj_status_t status;711 712 status = pj_sockaddr_set_str_addr(PJ_AF_INET6, &ipv6_loop, &loop);713 if (status != PJ_SUCCESS)714 return PJ_TRUE;715 716 if (pj_memcmp(&addr->ipv6.sin6_addr, &ipv6_loop.ipv6.sin6_addr, 16)==0)717 return PJ_FALSE;718 719 return PJ_TRUE;720 } else {721 return PJ_TRUE;722 }723 }724 725 693 /* Resolve the IP address of local machine */ 726 694 PJ_DEF(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr) … … 729 697 enum { 730 698 CAND_CNT = 8, 699 700 /* Weighting to be applied to found addresses */ 731 701 WEIGHT_HOSTNAME = 1, /* hostname IP is not always valid! */ 732 702 WEIGHT_DEF_ROUTE = 2, 733 WEIGHT_INTERFACE = 1 703 WEIGHT_INTERFACE = 1, 704 WEIGHT_LOOPBACK = -4, 705 WEIGHT_LINK_LOCAL = -3, 706 WEIGHT_DISABLED = -50, 707 708 MIN_WEIGHT = WEIGHT_DISABLED+1 /* minimum weight to use */ 734 709 }; 735 710 /* candidates: */ 736 711 pj_sockaddr cand_addr[CAND_CNT]; 737 unsignedcand_weight[CAND_CNT];712 int cand_weight[CAND_CNT]; 738 713 int selected_cand; 739 714 char strip[PJ_INET6_ADDRSTRLEN+10]; 715 /* Special IPv4 addresses. */ 716 struct spec_ipv4_t 717 { 718 pj_uint32_t addr; 719 pj_uint32_t mask; 720 int weight; 721 } spec_ipv4[] = 722 { 723 /* 127.0.0.0/8, loopback addr will be used if there is no other 724 * addresses. 725 */ 726 { 0x7f000000, 0xFF000000, WEIGHT_LOOPBACK }, 727 728 /* 0.0.0.0/8, special IP that doesn't seem to be practically useful */ 729 { 0x00000000, 0xFF000000, WEIGHT_DISABLED }, 730 731 /* 169.254.0.0/16, a zeroconf/link-local address, which has higher 732 * priority than loopback and will be used if there is no other 733 * valid addresses. 734 */ 735 { 0xa9fe0000, 0xFFFF0000, WEIGHT_LINK_LOCAL } 736 }; 737 /* Special IPv6 addresses */ 738 struct spec_ipv6_t 739 { 740 pj_uint8_t addr[16]; 741 pj_uint8_t mask[16]; 742 int weight; 743 } spec_ipv6[] = 744 { 745 /* Loopback address, ::1/128 */ 746 { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, 747 {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 748 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, 749 WEIGHT_LOOPBACK 750 }, 751 752 /* Link local, fe80::/10 */ 753 { {0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 754 {0xff,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 755 WEIGHT_LINK_LOCAL 756 }, 757 758 /* Disabled, ::/128 */ 759 { {0x0,0x0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 760 { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 761 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, 762 WEIGHT_DISABLED 763 } 764 }; 740 765 pj_addrinfo ai; 741 766 pj_status_t status; … … 848 873 } 849 874 875 /* Apply weight adjustment for special IPv4/IPv6 addresses 876 * See http://trac.pjsip.org/repos/ticket/1046 877 */ 878 if (af == PJ_AF_INET) { 879 for (i=0; i<cand_cnt; ++i) { 880 unsigned j; 881 for (j=0; j<PJ_ARRAY_SIZE(spec_ipv4); ++j) { 882 pj_uint32_t a = pj_ntohl(cand_addr[i].ipv4.sin_addr.s_addr); 883 pj_uint32_t pa = spec_ipv4[j].addr; 884 pj_uint32_t pm = spec_ipv4[j].mask; 885 886 if ((a & pm) == pa) { 887 cand_weight[i] += spec_ipv4[j].weight; 888 break; 889 } 890 } 891 } 892 } else if (af == PJ_AF_INET6) { 893 for (i=0; i<PJ_ARRAY_SIZE(spec_ipv6); ++i) { 894 unsigned j; 895 for (j=0; j<cand_cnt; ++j) { 896 pj_uint8_t *a = cand_addr[j].ipv6.sin6_addr.s6_addr; 897 pj_uint8_t am[16]; 898 pj_uint8_t *pa = spec_ipv6[i].addr; 899 pj_uint8_t *pm = spec_ipv6[i].mask; 900 unsigned k; 901 902 for (k=0; k<16; ++k) { 903 am[k] = (a[k] & pm[k]) & 0xFF; 904 } 905 906 if (pj_memcmp(am, pa, 16)==0) { 907 cand_weight[j] += spec_ipv6[i].weight; 908 } 909 } 910 } 911 } else { 912 return PJ_EAFNOTSUP; 913 } 914 850 915 /* Enumerate candidates to get the best IP address to choose */ 851 916 selected_cand = -1; … … 855 920 cand_weight[i])); 856 921 857 if ( !is_usable_ip(&cand_addr[i])) {922 if (cand_weight[i] < MIN_WEIGHT) { 858 923 continue; 859 924 }
Note: See TracChangeset
for help on using the changeset viewer.