static int rosedb_send_log(int sock, struct sockaddr *dst_addr, knot_pkt_t *pkt, const char *threat_code, struct query_data *qdata) { char buf[SYSLOG_BUFLEN]; char *stream = buf; size_t maxlen = sizeof(buf); time_t now = time(NULL); struct tm tm; localtime_r(&now, &tm); /* Add facility. */ STREAM_WRITE(stream, &maxlen, snprintf, "<%u>", SYSLOG_FACILITY); /* Current local time (4.3.2)*/ STREAM_WRITE(stream, &maxlen, strftime, "%b %d %H:%M:%S ", &tm); /* Host name / Component. */ STREAM_WRITE(stream, &maxlen, snprintf, "%s ", conf()->identity); STREAM_WRITE(stream, &maxlen, snprintf, "%s[%lu]: ", PACKAGE_NAME, (unsigned long) getpid()); /* Prepare log message line. */ int ret = rosedb_log_message(stream, &maxlen, pkt, threat_code, qdata); if (ret != KNOT_EOK) { return ret; } /* Send log message line. */ sendto(sock, buf, sizeof(buf) - maxlen, 0, dst_addr, sockaddr_len(dst_addr)); return ret; }
/* delete a portion of an index, adjusting offset appropriately. Returns 0 if things work and we should be called again, 1 if success full and done, and -1 if an error occurred. It adjusts offset appropriately on 0 or 1 return codes, and otherwise doesn't touch it */ static int ObliterateRegion(Volume * avp, VnodeClass aclass, StreamHandle_t * afile, afs_int32 * aoffset) { register struct VnodeClassInfo *vcp; Inode inodes[MAXOBLITATONCE]; register afs_int32 iindex, nscanned; afs_int32 offset; char buf[SIZEOF_LARGEDISKVNODE]; int hitEOF; register int i; register afs_int32 code; register struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf; hitEOF = 0; vcp = &VnodeClassInfo[aclass]; offset = *aoffset; /* original offset */ iindex = 0; nscanned = 0; /* advance over up to MAXOBLITATONCE inodes. nscanned tells us how many we examined. * We remember the inodes in an array, and idec them after zeroing them in the index. * The reason for these contortions is to make volume deletion idempotent, even * if we crash in the middle of a delete operation. */ STREAM_SEEK(afile, offset, 0); while (1) { if (iindex >= MAXOBLITATONCE) { break; } code = STREAM_READ(vnode, vcp->diskSize, 1, afile); nscanned++; offset += vcp->diskSize; if (code != 1) { hitEOF = 1; break; } if (vnode->type != vNull) { if (vnode->vnodeMagic != vcp->magic) goto fail; /* something really wrong; let salvager take care of it */ if (VNDISK_GET_INO(vnode)) inodes[iindex++] = VNDISK_GET_INO(vnode); } } /* next, obliterate the index and fflush (and fsync) it */ STREAM_SEEK(afile, *aoffset, 0); /* seek back to start of vnode index region */ memset(buf, 0, sizeof(buf)); /* zero out our proto-vnode */ for (i = 0; i < nscanned; i++) { if (STREAM_WRITE(buf, vcp->diskSize, 1, afile) != 1) goto fail; } STREAM_FLUSH(afile); /* ensure 0s are on the disk */ OS_SYNC(afile->str_fd); /* finally, do the idec's */ for (i = 0; i < iindex; i++) { IH_DEC(V_linkHandle(avp), inodes[i], V_parentId(avp)); DOPOLL; } /* return the new offset */ *aoffset = offset; return hitEOF; /* return 1 if hit EOF (don't call again), otherwise 0 */ fail: return -1; }
static int rosedb_log_message(char *stream, size_t *maxlen, knot_pkt_t *pkt, const char *threat_code, struct query_data *qdata) { char dname_buf[KNOT_DNAME_MAXLEN] = {'\0'}; struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); time_t now = time(NULL); struct tm tm; gmtime_r(&now, &tm); /* Field 1 Timestamp (UTC). */ STREAM_WRITE(stream, maxlen, strftime, "%Y-%m-%d %H:%M:%S\t", &tm); /* Field 2/3 Remote, local address. */ const struct sockaddr *remote = (const struct sockaddr *)qdata->param->remote; memcpy(&addr, remote, sockaddr_len(remote)); int client_port = sockaddr_port(&addr); sockaddr_port_set(&addr, 0); STREAM_WRITE(stream, maxlen, sockaddr_tostr, &addr); STREAM_WRITE(stream, maxlen, snprintf, "\t"); getsockname(qdata->param->socket, (struct sockaddr *)&addr, &addr_len); int server_port = sockaddr_port(&addr); sockaddr_port_set(&addr, 0); STREAM_WRITE(stream, maxlen, sockaddr_tostr, &addr); STREAM_WRITE(stream, maxlen, snprintf, "\t"); /* Field 4/5 Local, remote port. */ STREAM_WRITE(stream, maxlen, snprintf, "%d\t%d\t", client_port, server_port); /* Field 6 Threat ID. */ STREAM_WRITE(stream, maxlen, snprintf, "%s\t", threat_code); /* Field 7 - 13 NULL */ STREAM_WRITE(stream, maxlen, snprintf, "\t\t\t\t\t\t\t"); /* Field 14 QNAME */ knot_dname_to_str(dname_buf, knot_pkt_qname(qdata->query), sizeof(dname_buf)); STREAM_WRITE(stream, maxlen, snprintf, "%s\t", dname_buf); /* Field 15 Resolution (0 = local, 1 = lookup)*/ STREAM_WRITE(stream, maxlen, snprintf, "0\t"); /* Field 16 RDATA. * - Return randomly RDATA in the answer section (probabilistic rotation). * - Empty if no answer. */ const knot_pktsection_t *ans = knot_pkt_section(pkt, KNOT_ANSWER); if (ans->count > 0) { const knot_rrset_t *rr = &ans->rr[knot_random_uint16_t() % ans->count]; int ret = knot_rrset_txt_dump_data(rr, 0, stream, *maxlen, &KNOT_DUMP_STYLE_DEFAULT); if (ret < 0) { return ret; } stream_skip(&stream, maxlen, ret); } STREAM_WRITE(stream, maxlen, snprintf, "\t"); /* Field 17 Connection type. */ STREAM_WRITE(stream, maxlen, snprintf, "%s\t", net_is_connected(qdata->param->socket) ? "TCP" : "UDP"); /* Field 18 Query type. */ char type_str[16] = { '\0' }; knot_rrtype_to_string(knot_pkt_qtype(qdata->query), type_str, sizeof(type_str)); STREAM_WRITE(stream, maxlen, snprintf, "%s\t", type_str); /* Field 19 First authority. */ const knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY); if (ns->count > 0 && ns->rr[0].type == KNOT_RRTYPE_NS) { const knot_dname_t *label = knot_ns_name(&ns->rr[0].rrs, 0); memset(dname_buf, 0, sizeof(dname_buf)); memcpy(dname_buf, label + 1, *label); STREAM_WRITE(stream, maxlen, snprintf, "%s", dname_buf); } return KNOT_EOK; }