Given all addresses assigned to a specific interface ('laddr' parameter), this function returns the "candidate set" associated with 'addr/plen'. Basically, the function filters all interface addresses to keep only those that have the same scope as provided prefix. This is on t
(
addr, # type: str
plen, # type: int
laddr # type: Iterator[Tuple[str, int, str]]
)
| 39 | |
| 40 | |
| 41 | def construct_source_candidate_set( |
| 42 | addr, # type: str |
| 43 | plen, # type: int |
| 44 | laddr # type: Iterator[Tuple[str, int, str]] |
| 45 | ): |
| 46 | # type: (...) -> List[str] |
| 47 | """ |
| 48 | Given all addresses assigned to a specific interface ('laddr' parameter), |
| 49 | this function returns the "candidate set" associated with 'addr/plen'. |
| 50 | |
| 51 | Basically, the function filters all interface addresses to keep only those |
| 52 | that have the same scope as provided prefix. |
| 53 | |
| 54 | This is on this list of addresses that the source selection mechanism |
| 55 | will then be performed to select the best source address associated |
| 56 | with some specific destination that uses this prefix. |
| 57 | """ |
| 58 | def cset_sort(x, y): |
| 59 | # type: (str, str) -> int |
| 60 | x_global = 0 |
| 61 | if in6_isgladdr(x): |
| 62 | x_global = 1 |
| 63 | y_global = 0 |
| 64 | if in6_isgladdr(y): |
| 65 | y_global = 1 |
| 66 | res = y_global - x_global |
| 67 | if res != 0 or y_global != 1: |
| 68 | return res |
| 69 | # two global addresses: if one is native, it wins. |
| 70 | if not in6_isaddr6to4(x): |
| 71 | return -1 |
| 72 | return -res |
| 73 | |
| 74 | cset = iter([]) # type: Iterator[Tuple[str, int, str]] |
| 75 | if in6_isgladdr(addr) or in6_isuladdr(addr): |
| 76 | cset = (x for x in laddr if x[1] == IPV6_ADDR_GLOBAL) |
| 77 | elif in6_islladdr(addr): |
| 78 | cset = (x for x in laddr if x[1] == IPV6_ADDR_LINKLOCAL) |
| 79 | elif in6_issladdr(addr): |
| 80 | cset = (x for x in laddr if x[1] == IPV6_ADDR_SITELOCAL) |
| 81 | elif in6_ismaddr(addr): |
| 82 | if in6_ismnladdr(addr): |
| 83 | cset = (x for x in [('::1', 16, conf.loopback_name)]) |
| 84 | elif in6_ismgladdr(addr): |
| 85 | cset = (x for x in laddr if x[1] == IPV6_ADDR_GLOBAL) |
| 86 | elif in6_ismlladdr(addr): |
| 87 | cset = (x for x in laddr if x[1] == IPV6_ADDR_LINKLOCAL) |
| 88 | elif in6_ismsladdr(addr): |
| 89 | cset = (x for x in laddr if x[1] == IPV6_ADDR_SITELOCAL) |
| 90 | elif addr == '::' and plen == 0: |
| 91 | cset = (x for x in laddr if x[1] == IPV6_ADDR_GLOBAL) |
| 92 | elif addr == '::1': |
| 93 | cset = (x for x in laddr if x[1] == IPV6_ADDR_LOOPBACK) |
| 94 | addrs = [x[0] for x in cset] |
| 95 | # TODO convert the cmd use into a key |
| 96 | addrs.sort(key=cmp_to_key(cset_sort)) # Sort with global addresses first |
| 97 | return addrs |
| 98 |
no test coverage detected