diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dhcpv6-ia.c | 82 |
1 files changed, 43 insertions, 39 deletions
diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c index 98fb460..e1d0278 100644 --- a/src/dhcpv6-ia.c +++ b/src/dhcpv6-ia.c @@ -71,10 +71,10 @@ int setup_dhcpv6_ia_interface(struct interface *iface, bool enable) list_add(&border->head, &iface->ia_assignments); } - // Parse static entries + /* Parse static entries */ struct lease *lease; list_for_each_entry(lease, &leases, head) { - // Construct entry + /* Construct entry */ size_t duid_len = lease->duid_len ? lease->duid_len : 14; struct dhcpv6_assignment *a = calloc(1, sizeof(*a) + duid_len); if (!a) { @@ -94,6 +94,7 @@ int setup_dhcpv6_ia_interface(struct interface *iface, bool enable) uint32_t i4a = ntohl(lease->ipaddr.s_addr) & 0xff; a->assigned = ((i4a / 100) << 8) | (((i4a % 100) / 10) << 4) | (i4a % 10); } + odhcpd_urandom(a->key, sizeof(a->key)); memcpy(a->clid_data, lease->duid, lease->duid_len); memcpy(a->mac, lease->mac.ether_addr_octet, sizeof(a->mac)); @@ -108,10 +109,9 @@ int setup_dhcpv6_ia_interface(struct interface *iface, bool enable) if (c->length != 128 || c->assigned > a->assigned) { list_add_tail(&a->head, &c->head); break; - } else if (c->assigned == a->assigned) { - // Already an assignment with that number + } else if (c->assigned == a->assigned) + /* Already an assignment with that number */ break; - } } if (a->head.next) { @@ -442,12 +442,14 @@ static void managed_handle_pd_data(struct ustream *s, _unused int bytes_new) } -// TCP transmission has ended, either because of success or timeout or other error +/* TCP transmission has ended, either because of success or timeout or other error */ static void managed_handle_pd_done(struct ustream *s) { struct dhcpv6_assignment *c = container_of(s, struct dhcpv6_assignment, managed_sock); + c->valid_until = odhcpd_time() + 15; c->managed_size = 0; + if (c->accept_reconf) c->reconf_cnt = 1; } @@ -472,7 +474,7 @@ static bool assign_pd(struct interface *iface, struct dhcpv6_assignment *assign) assign->valid_until = odhcpd_time() + 15; list_add(&assign->head, &iface->ia_assignments); - // Wait initial period of up to 250ms for immediate assignment + /* Wait initial period of up to 250ms for immediate assignment */ struct pollfd pfd = { .fd = fd, .events = POLLIN }; poll(&pfd, 1, 250); managed_handle_pd_data(&assign->managed_sock.stream, 0); @@ -482,11 +484,10 @@ static bool assign_pd(struct interface *iface, struct dhcpv6_assignment *assign) } return false; - } else if (iface->ia_addr_len < 1) { + } else if (iface->ia_addr_len < 1) return false; - } - // Try honoring the hint first + /* Try honoring the hint first */ uint32_t current = 1, asize = (1 << (64 - assign->length)) - 1; if (assign->assigned) { list_for_each_entry(c, &iface->ia_assignments, head) { @@ -504,7 +505,7 @@ static bool assign_pd(struct interface *iface, struct dhcpv6_assignment *assign) } } - // Fallback to a variable assignment + /* Fallback to a variable assignment */ current = 1; list_for_each_entry(c, &iface->ia_assignments, head) { if (c->length == 128 || c->length == 0) @@ -527,13 +528,13 @@ static bool assign_pd(struct interface *iface, struct dhcpv6_assignment *assign) static bool assign_na(struct interface *iface, struct dhcpv6_assignment *assign) { - // Seed RNG with checksum of DUID + /* Seed RNG with checksum of DUID */ uint32_t seed = 0; for (size_t i = 0; i < assign->clid_len; ++i) seed += assign->clid_data[i]; srand(seed); - // Try to assign up to 100x + /* Try to assign up to 100x */ for (size_t i = 0; i < 100; ++i) { uint32_t try; do try = ((uint32_t)rand()) % 0x0fff; while (try < 0x100); @@ -547,9 +548,8 @@ static bool assign_na(struct interface *iface, struct dhcpv6_assignment *assign) assign->assigned = try; list_add_tail(&assign->head, &c->head); return true; - } else if (c->assigned == try) { + } else if (c->assigned == try) break; - } } } @@ -563,6 +563,7 @@ void dhcpv6_ia_preupdate(struct interface *iface) struct dhcpv6_assignment *c, *border = list_last_entry( &iface->ia_assignments, struct dhcpv6_assignment, head); + list_for_each_entry(c, &iface->ia_assignments, head) if (c != border && !iface->managed) apply_lease(iface, c, false); @@ -583,6 +584,7 @@ void dhcpv6_ia_postupdate(struct interface *iface, time_t now) struct dhcpv6_assignment *border = list_last_entry( &iface->ia_assignments, struct dhcpv6_assignment, head); + if (minprefix > 32 && minprefix <= 64) border->assigned = 1U << (64 - minprefix); else @@ -605,7 +607,7 @@ void dhcpv6_ia_postupdate(struct interface *iface, time_t now) c->reconf_sent = now; send_reconf(iface, c); - // Leave all other assignments of that client alone + /* Leave all other assignments of that client alone */ struct dhcpv6_assignment *a; list_for_each_entry(a, &iface->ia_assignments, head) if (a != c && a->clid_len == c->clid_len && @@ -677,11 +679,11 @@ static size_t append_reply(uint8_t *buf, size_t buflen, uint16_t status, } else { if (a) { uint32_t leasetime; - if (a->leasetime > 0) { + if (a->leasetime > 0) leasetime = a->leasetime; - } else { + else leasetime = iface->dhcpv4_leasetime; - } + if (leasetime == 0) leasetime = 3600; else if (leasetime < 60) @@ -756,7 +758,7 @@ static size_t append_reply(uint8_t *buf, size_t buflen, uint16_t status, datalen += entrlen + 4; } - // Calculate T1 / T2 based on non-deprecated addresses + /* Calculate T1 / T2 based on non-deprecated addresses */ if (prefix_pref > 0) { if (prefix_pref < pref) pref = prefix_pref; @@ -944,8 +946,7 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, const struct dhcpv6_client_header *hdr = data; uint8_t *start = (uint8_t*)&hdr[1], *odata; uint16_t otype, olen; - - // Find and parse client-id and hostname + /* Find and parse client-id and hostname */ bool accept_reconf = false; uint8_t *clid_data = NULL, clid_len = 0, mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; char hostname[256]; @@ -972,9 +973,8 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, if (dn_expand(&fqdn_buf[1], &fqdn_buf[olen], &fqdn_buf[1], hostname, sizeof(hostname)) > 0) hostname_len = strcspn(hostname, "."); - } else if (otype == DHCPV6_OPT_RECONF_ACCEPT) { + } else if (otype == DHCPV6_OPT_RECONF_ACCEPT) accept_reconf = true; - } } if (!clid_data || !clid_len || clid_len > 130) @@ -993,7 +993,7 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, uint8_t reqlen = (is_pd) ? 62 : 128; uint32_t reqhint = 0; - // Parse request hint for IA-PD + /* Parse request hint for IA-PD */ if (is_pd) { uint8_t *sdata; uint16_t stype, slen; @@ -1023,7 +1023,7 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, } } - // Find assignment + /* Find assignment */ struct dhcpv6_assignment *c, *a = NULL; list_for_each_entry(c, &iface->ia_assignments, head) { if (((c->clid_len == clid_len && !memcmp(c->clid_data, clid_data, clid_len)) || @@ -1045,14 +1045,16 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, } } - // Generic message handling + /* Generic message handling */ uint16_t status = DHCPV6_STATUS_OK; - if (a && a->managed_size < 0) { + if (a && a->managed_size < 0) return -1; - } else if (hdr->msg_type == DHCPV6_MSG_SOLICIT || hdr->msg_type == DHCPV6_MSG_REQUEST) { + + if (hdr->msg_type == DHCPV6_MSG_SOLICIT || hdr->msg_type == DHCPV6_MSG_REQUEST) { bool assigned = !!a; - if (!a && !iface->no_dynamic_dhcp) { // Create new binding + if (!a && !iface->no_dynamic_dhcp) { + /* Create new binding */ a = calloc(1, sizeof(*a) + clid_len); if (a) { a->clid_len = clid_len; @@ -1060,8 +1062,8 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, a->length = reqlen; a->peer = *addr; a->assigned = reqhint; - // Set valid time to current time indicating - // assignment is not having infinite lifetime + /* Set valid time to current time indicating */ + /* assignment is not having infinite lifetime */ a->valid_until = now; if (first) @@ -1081,9 +1083,10 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, } } - if (!assigned || iface->ia_addr_len == 0) { // Set error status + if (!assigned || iface->ia_addr_len == 0) + /* Set error status */ status = (is_pd) ? DHCPV6_STATUS_NOPREFIXAVAIL : DHCPV6_STATUS_NOADDRSAVAIL; - } else if (assigned && !first) { // + else if (assigned && !first) { size_t handshake_len = 4; buf[0] = 0; buf[1] = DHCPV6_OPT_RECONF_ACCEPT; @@ -1113,7 +1116,7 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, ia_response_len = append_reply(buf, buflen, status, ia, a, iface, true); - // Was only a solicitation: mark binding for removal + /* Was only a solicitation: mark binding for removal */ if (assigned && hdr->msg_type == DHCPV6_MSG_SOLICIT) { a->flags &= ~OAF_BOUND; @@ -1130,9 +1133,10 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, a->accept_reconf = accept_reconf; a->flags |= OAF_BOUND; apply_lease(iface, a, true); - } else if (!assigned && a && a->managed_size == 0) { // Cleanup failed assignment + } else if (!assigned && a && a->managed_size == 0) + /* Cleanup failed assignment */ free_dhcpv6_assignment(a); - } + } else if (hdr->msg_type == DHCPV6_MSG_RENEW || hdr->msg_type == DHCPV6_MSG_RELEASE || hdr->msg_type == DHCPV6_MSG_REBIND || @@ -1158,11 +1162,11 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, if (!(a->flags & OAF_STATIC)) { a->clid_len = 0; - a->valid_until = now + 3600; // Block address for 1h + a->valid_until = now + 3600; /* Block address for 1h */ } } } else if (hdr->msg_type == DHCPV6_MSG_CONFIRM && ia_addr_present) { - // Send NOTONLINK for CONFIRM with addr present so that clients restart connection + /* Send NOTONLINK for CONFIRM with addr present so that clients restart connection */ status = DHCPV6_STATUS_NOTONLINK; ia_response_len = append_reply(buf, buflen, status, ia, a, iface, true); notonlink = true; |