int flushbuf() { struct sockaddr_in6 tob, *to; int rc; if(!buffered) return 0; if(buffered_interface) { memset(&tob, 0, sizeof(tob)); tob.sin6_family = AF_INET6; memcpy(&tob.sin6_addr, &protocol_group, 16); tob.sin6_port = htons(protocol_port); tob.sin6_scope_id = buffered_interface->ifindex; to = &tob; } else { to = &buffered_sin6; } rc = sendto(protocol_socket, sendbuf, buffered, 0, (struct sockaddr*)to, sizeof(struct sockaddr_in6)); if(rc < 0) { int saved_errno = errno; perror("sendto"); errno = saved_errno; } buffered_interface = NULL; buffered = 0; MEM_UNDEFINED(sendbuf, SENDBUF_SIZE); MEM_UNDEFINED(&buffered_sin6, sizeof(buffered_sin6)); return rc; }
static int send_ra(struct interface *interface, const struct sockaddr_in6 *to, int router) { int buflen = 1024; unsigned char buf[buflen]; int i = 0, j; struct prefix_list *d; MEM_UNDEFINED(buf, buflen); CHECK(16); BYTE(134); BYTE(0); SHORT(0); BYTE(0); BYTE(0); SHORT(router >= 2 ? 3600 : 0); LONG(0); LONG(0); if(interface) { if(interface->retractions) { for(j = 0; j < interface->retractions->numprefixes; j++) { struct prefix *p = &interface->retractions->prefixes[j]; CHECK(32); BYTE(3); BYTE(4); BYTE(p->plen); BYTE(0x80); LONG(0); LONG(0); LONG(0); BYTES(&p->p, 16); } } destroy_prefix_list(interface->retractions); interface->retractions = NULL; if(router >= 1) { for(j = 0; j < interface->numassigned; j++) { struct assigned_prefix *ap = &interface->assigned[j]; struct prefix *p = &ap->assigned; if(!ap->applied || prefix_v4(&ap->assigned) || p->plen >= 128) continue; CHECK(32); BYTE(3); BYTE(4); BYTE(p->plen); BYTE(router <= 0 ? 0x80 : (0x80 | 0x40)); LONG(router <= 0 ? 0 : 3600); LONG(router <= 0 ? 0 : 1800); LONG(0); BYTES(&p->p, 16); } } } d = all_delegated_prefixes(); if(d && d->numprefixes > 0) { for(j = 0; j < d->numprefixes; j++) { struct prefix *p = &d->prefixes[j]; if(prefix_v4(p)) { continue; } CHECK(32); BYTE(24); BYTE(p->plen > 64 ? 3 : 2); BYTE(p->plen); BYTE(0); LONG(router >= 1 ? 3600 : 0); BYTES(&p->p, p->plen > 64 ? 16 : 8); } } destroy_prefix_list(d); if(router >= 1) { struct prefix_list *dns = all_dhcp_data(0, 0, 1); if(dns && dns->numprefixes > 0) { CHECK(8 + dns->numprefixes * 16); BYTE(25); BYTE(1 + dns->numprefixes * 2); SHORT(0); LONG(MAX_RTR_ADV_INTERVAL * 3 / 2); for(j = 0; j < dns->numprefixes; j++) { BYTES(&dns->prefixes[j].p, 16); } } destroy_prefix_list(dns); } sendit: debugf("-> Router Advertisement\n"); return sendto(ra_socket, buf, i, 0, (struct sockaddr*)to, sizeof(*to)); }
int format_my_state(unsigned char *buf, int buflen) { int i = 0, j, k; struct node *node = find_node(myid, 0); int dlen, n_dns6, dns6_len, n_dns4, dns4_len; MEM_UNDEFINED(buf, buflen); for(j = 0; j < numneighs; j++) { CHECK(12); SHORT(8); SHORT(12); BYTES(neighs[j].id, 4); LONG(neighs[j].eid); LONG(neighs[j].interface->ifindex); PAD(); } CHECK(11); SHORT(32); SHORT(12); SHORT(0); BYTE(0); BYTE(interface_dhcpv4_prio(neighs[j].interface) & 0x0F); BYTES("SHNCPD/0", 8); PAD(); for(j = 0; j < numinterfaces; j++) { for(k = 0; k < interfaces[j].numassigned; k++) { const struct assigned_prefix *aa = &interfaces[j].assigned[k]; int pbytes = (aa->assigned.plen + 7) / 8; if(aa->published) { assert(aa->assigned.plen > 0); CHECK(10 + pbytes); SHORT(35); SHORT(6 + pbytes); LONG(interfaces[j].ifindex); BYTE((aa->assigned.prio & 0x0F)); BYTE(aa->assigned.plen); BYTES(&aa->assigned.p, pbytes); PAD(); } if(!IN6_IS_ADDR_UNSPECIFIED(&aa->assigned_address)) { CHECK(24); SHORT(36); SHORT(20); LONG(interfaces[j].ifindex); BYTES(&aa->assigned_address, 16); PAD(); } } } dlen = n_dns6 = n_dns4 = 0; for(j = 0; j < node->numexts; j++) { if(node->exts[j]->delegated) { for(k = 0; k < node->exts[j]->delegated->numprefixes; k++) { struct prefix *p = &node->exts[j]->delegated->prefixes[k]; dlen += 4 + 9 + (p->plen + 7) / 8; } } if(node->exts[j]->dns) { for(k = 0; k < node->exts[j]->dns->numprefixes; k++) { struct prefix *p = &node->exts[j]->dns->prefixes[k]; if(!prefix_v4(p)) n_dns6++; else n_dns4++; } } } dns6_len = n_dns6 > 0 ? 4 + 4 + 16 * n_dns6 : 0; dns4_len = n_dns4 > 0 ? 4 + 2 + 4 * n_dns4 : 0; for(j = 0; j < node->numexts; j++) { CHECK(4); SHORT(33); SHORT(dlen + (-dlen & 3) + dns6_len + (-dns6_len & 3) + dns4_len + (-dns4_len & 3)); if(node->exts[j]->delegated) { for(k = 0; k < node->exts[j]->delegated->numprefixes; k++) { struct prefix *p = &node->exts[j]->delegated->prefixes[k]; CHECK(4 + 9 + (p->plen + 7) / 8 + 4); SHORT(34); SHORT(9 + (p->plen + 7) / 8); LONG(3600); LONG(1800); BYTE(p->plen); BYTES(&p->p, (p->plen + 7) / 8); PAD(); } } if(n_dns6 > 0) { CHECK(4 + 4 + 16 * n_dns6 + 4); SHORT(37); SHORT(4 + 16 * n_dns6); SHORT(23); SHORT(16 * n_dns6); for(k = 0; k < node->exts[j]->dns->numprefixes; k++) { struct prefix *p = &node->exts[j]->dns->prefixes[k]; if(!prefix_v4(p)) { BYTES(&p->p, 16); } } PAD(); } if(n_dns4 > 0) { CHECK(4 + 2 + 4 * n_dns4 + 4); SHORT(38); SHORT(2 + 4 * n_dns4); BYTE(6); BYTE(4 * n_dns4); for(k = 0; k < node->exts[j]->dns->numprefixes; k++) { struct prefix *p = &node->exts[j]->dns->prefixes[k]; if(prefix_v4(p)) { BYTES((char*)&p->p + 12, 4); } } PAD(); } } return i; fail: return -1; }
void* touch_mem(void* arg) { struct AllocTouchMem* touch_mem_ptr = (struct AllocTouchMem*)arg; size_t sz = touch_mem_ptr->sz; Uint32 index = touch_mem_ptr->index; unsigned char *p = (unsigned char *)touch_mem_ptr->p; size_t num_pages_per_thread = 1; size_t first_page; size_t tot_pages = (sz + (TOUCH_PAGE_SIZE - 1)) / TOUCH_PAGE_SIZE; if (tot_pages > TOUCH_PARALLELISM) { num_pages_per_thread = ((tot_pages + (TOUCH_PARALLELISM - 1)) / TOUCH_PARALLELISM); } first_page = index * num_pages_per_thread; if (first_page >= tot_pages) { return NULL; /* We're done, no page to handle */ } else if ((tot_pages - first_page) < num_pages_per_thread) { num_pages_per_thread = tot_pages - first_page; } unsigned char * ptr = (unsigned char*)(p + (first_page * 4096)); for (Uint32 i = 0; i < num_pages_per_thread; ptr += TOUCH_PAGE_SIZE, i++) { *ptr = 0; if (i % NUM_PAGES_BETWEEN_WATCHDOG_SETS == 0) { /* Roughly every 120 ms we come here in worst case */ *(touch_mem_ptr->watchCounter) = 9; } if (debugUinitMemUse) { const unsigned char* end = p + sz; const size_t size = MIN(TOUCH_PAGE_SIZE, end - ptr); /* Initialize the memory to something likely to trigger access violations if used as a pointer or array index, to make it easier to detect use of uninitialized memory. See also TRASH macro. */ MEM_CHECK_ADDRESSABLE(ptr, size); memset(ptr, 0xfb, size); /* Mark memory as being undefined for valgrind, so that valgrind may know that reads from this memory is an error. */ MEM_UNDEFINED(ptr, size); *(touch_mem_ptr->watchCounter) = 9; } } return NULL; }