This function implement a limited version of source address selection algorithm defined in section 5 of RFC 3484. The format is very different from that described in the document because it operates on a set of candidate source address for some specific route.
(dst, candidate_set)
| 98 | |
| 99 | |
| 100 | def get_source_addr_from_candidate_set(dst, candidate_set): |
| 101 | # type: (str, List[str]) -> str |
| 102 | """ |
| 103 | This function implement a limited version of source address selection |
| 104 | algorithm defined in section 5 of RFC 3484. The format is very different |
| 105 | from that described in the document because it operates on a set |
| 106 | of candidate source address for some specific route. |
| 107 | """ |
| 108 | |
| 109 | def scope_cmp(a, b): |
| 110 | # type: (str, str) -> int |
| 111 | """ |
| 112 | Given two addresses, returns -1, 0 or 1 based on comparison of |
| 113 | their scope |
| 114 | """ |
| 115 | scope_mapper = {IPV6_ADDR_GLOBAL: 4, |
| 116 | IPV6_ADDR_SITELOCAL: 3, |
| 117 | IPV6_ADDR_LINKLOCAL: 2, |
| 118 | IPV6_ADDR_LOOPBACK: 1} |
| 119 | sa = in6_getscope(a) |
| 120 | if sa == -1: |
| 121 | sa = IPV6_ADDR_LOOPBACK |
| 122 | sb = in6_getscope(b) |
| 123 | if sb == -1: |
| 124 | sb = IPV6_ADDR_LOOPBACK |
| 125 | |
| 126 | sa = scope_mapper[sa] |
| 127 | sb = scope_mapper[sb] |
| 128 | |
| 129 | if sa == sb: |
| 130 | return 0 |
| 131 | if sa > sb: |
| 132 | return 1 |
| 133 | return -1 |
| 134 | |
| 135 | def rfc3484_cmp(source_a, source_b): |
| 136 | # type: (str, str) -> int |
| 137 | """ |
| 138 | The function implements a limited version of the rules from Source |
| 139 | Address selection algorithm defined section of RFC 3484. |
| 140 | """ |
| 141 | |
| 142 | # Rule 1: Prefer same address |
| 143 | if source_a == dst: |
| 144 | return 1 |
| 145 | if source_b == dst: |
| 146 | return 1 |
| 147 | |
| 148 | # Rule 2: Prefer appropriate scope |
| 149 | tmp = scope_cmp(source_a, source_b) |
| 150 | if tmp == -1: |
| 151 | if scope_cmp(source_a, dst) == -1: |
| 152 | return 1 |
| 153 | else: |
| 154 | return -1 |
| 155 | elif tmp == 1: |
| 156 | if scope_cmp(source_b, dst) == -1: |
| 157 | return 1 |
no outgoing calls
no test coverage detected
searching dependent graphs…