static void output_stream_write_rrsig_wire(output_stream* os, u8* label, u32 label_len, u8* origin, u32 origin_len, zdb_packed_ttlrdata* sig_sll) { while(sig_sll != NULL) { output_stream_write(os, label, label_len); output_stream_write(os, origin, origin_len); output_stream_write_u16(os, TYPE_RRSIG); /** @note NATIVETYPE */ output_stream_write_u16(os, CLASS_IN); /** @note NATIVECLASS */ output_stream_write_nu32(os, sig_sll->ttl); output_stream_write_nu16(os, sig_sll->rdata_size); output_stream_write(os, &sig_sll->rdata_start[0], sig_sll->rdata_size); #ifndef NDEBUG rdata_desc rdatadesc = {TYPE_RRSIG, sig_sll->rdata_size, &sig_sll->rdata_start[0]}; if(origin != NULL) { log_debug("incremental: %{dnslabel}%{dnsname} %d IN %{typerdatadesc}", label, origin, sig_sll->ttl, &rdatadesc); } else { log_debug("incremental: %{dnsname} %d IN %{typerdatadesc}", label, sig_sll->ttl, &rdatadesc); } #endif sig_sll = sig_sll->next; } }
ya_result output_stream_decode_base32hex(output_stream* os, const char * string, u32 length) { char buffer[64]; u8 buffer_bin[40]; u32 needle = 0; ya_result return_code = OK; /* ------------------------------------------------------------ */ while(length-- > 0) { char c = *string++; if(isspace(c)) { continue; } buffer[needle++] = c; if(needle == sizeof (buffer)) { if(FAIL(return_code = base32hex_decode(buffer, needle, buffer_bin))) { return return_code; } if(FAIL(return_code = output_stream_write(os, buffer_bin, return_code))) { return return_code; } needle = 0; } } if(needle > 0) { if((needle & 7) != 0) { return PARSEB32H_ERROR; } if(FAIL(return_code = base32hex_decode(buffer, needle, buffer_bin))) { return return_code; } if(FAIL(return_code = output_stream_write(os, buffer_bin, return_code))) { return return_code; } } return return_code; }
static ya_result logger_channel_file_constmsg(logger_channel* chan, int level, char* text, u32 text_len, u32 date_offset) { file_data* sd = (file_data*)chan->data; output_stream_write(&sd->os, (const u8*)text, text_len); ya_result ret = output_stream_write(&sd->os, (const u8*)"\n", 1); if(sd->force_flush) { output_stream_flush(&sd->os); } return ret; }
static void output_stream_write_wire(output_stream* os, dnslabel_vector_reference labels, s32 top, u16 type, zdb_ttlrdata* record) { output_stream_write_dnslabel_vector(os, labels, top); output_stream_write_u16(os, type); /** @note NATIVETYPE */ output_stream_write_u16(os, CLASS_IN); /** @note NATIVECLASS */ output_stream_write_nu32(os, record->ttl); output_stream_write_nu16(os, record->rdata_size); output_stream_write(os, record->rdata_pointer, record->rdata_size); }
static void output_stream_write_wire_dnsname(output_stream* os, const u8 *dnsname, u16 type, zdb_ttlrdata* record) { output_stream_write_dnsname(os, dnsname); output_stream_write_u16(os, type); /** @note NATIVETYPE */ output_stream_write_u16(os, CLASS_IN); /** @note NATIVECLASS */ output_stream_write_nu32(os, record->ttl); output_stream_write_nu16(os, record->rdata_size); output_stream_write(os, record->rdata_pointer, record->rdata_size); }
ya_result output_stream_write_pu32(output_stream* os, u32 value) { u8 v; while(value > 127) { v = (u8)value; value >>= 7; v |= 0x80; /* I'll only check the error for the last byte */ output_stream_write(os, &v, 1); } v = (u8)value; return output_stream_write(os, &v, 1); }
ya_result output_stream_write_nu16(output_stream* os, u16 value) { u8 buffer[2]; /* ------------------------------------------------------------ */ buffer[0] = value >> 8; buffer[1] = value; return output_stream_write(os, buffer, 2); }
ya_result output_stream_write_nu32(output_stream* os, u32 value) { u8 buffer[4]; /* ------------------------------------------------------------ */ buffer[0] = value >> 24; buffer[1] = value >> 16; buffer[2] = value >> 8; buffer[3] = value; return output_stream_write(os, buffer, 4); }
static ya_result logger_channel_file_vmsg(logger_channel* chan, int level, char* text, va_list args) { file_data* sd = (file_data*)chan->data; vosformat(&sd->os, text, args); ya_result ret = output_stream_write(&sd->os, (const u8*)"\n", 1); if(sd->force_flush) { output_stream_flush(&sd->os); } return ret; }
static ya_result counter_write(output_stream* stream, const u8* counter_, u32 len) { counter_output_stream_data* data = (counter_output_stream_data*)stream->data; data->write_count += len; if(ISOK(data->result)) { data->result = output_stream_write(data->filtered, counter_, len); if(ISOK(data->result)) { data->writed_count += data->result; } } return data->result; }
ya_result output_stream_write_dnslabel_stack(output_stream* os, dnslabel_stack_reference labels, s32 top) { ya_result n = 0; s32 i; for(i = top; i >= 0; i--) { ya_result err; u8 len = labels[i][0] + 1; if(FAIL(err = output_stream_write(os, labels[i], len))) { return err; } n += err; } output_stream_write_u8(os, 0); return n; }
void log_memdump_ex(logger_handle* hndl, u32 level, const void* data_pointer_, size_t size_, size_t line_size, bool hex, bool text, bool address) { if((hndl == NULL) || (level >= MSG_LEVEL_COUNT) || (hndl->channels[level].offset < 0)) { return; } output_stream os; char buffer[4096]; bytearray_output_stream_init((u8*)buffer, sizeof (buffer), &os); u8* data_pointer = (u8*)data_pointer_; s32 size = size_; int dump_size; int i; do { dump_size = MIN(line_size, size); u8* data; if(address) { osformat(&os, "%p ", data_pointer); } if(hex) { data = data_pointer; for(i = 0; i < dump_size; i++) { osformat(&os, "%02x", *data++); if((i & 3) == 3) { output_stream_write_u8(&os, (u8)' '); } } for(; i < line_size; i++) { osprint(&os, " "); if((i & 3) == 0) { osprint(&os, " "); } } } if(hex & text) { output_stream_write(&os, (u8*)" | ", 3); } if(text) { data = data_pointer; for(i = 0; i < dump_size; i++) { char c = *data++; if(c < ' ') { c = '.'; } else if(c == '%') { output_stream_write_u8(&os, '%'); } output_stream_write_u8(&os, (u8)c); } } data_pointer += dump_size; size -= dump_size; if(size != 0) { output_stream_write_u8(&os, 0); logger_handle_msg(hndl, level, "%s", bytearray_output_stream_buffer(&os)); bytearray_output_stream_reset(&os); } } while(size > 0); //if(size_ > line_size) if(bytearray_output_stream_size(&os) > 0) { output_stream_write_u8(&os, 0); logger_handle_msg(hndl, level, "%s", bytearray_output_stream_buffer(&os)); } output_stream_close(&os); }
static ya_result xfr_input_stream_read_packet(xfr_input_stream_data *data) { message_data *message = data->message; packet_unpack_reader_data *reader = &data->reader; u8 *record = &message->pool_buffer[0]; u32 record_len; ya_result return_value = SUCCESS; #if DEBUG_XFR_INPUT_STREAM log_debug("xfr_input_stream_read_packet(%p) ancount=%hd record_index=%u", data, data->ancount, data->record_index); #endif while((data->ancount > 0) && (pipe_stream_write_available(&data->pipe_stream_output) > 2048 )) { --data->ancount; if(FAIL(record_len = packet_reader_read_record(reader, record, RDATA_MAX_LENGTH + 1))) { if(record_len != UNSUPPORTED_TYPE) { data->eos = TRUE; return_value = record_len; break; } log_err("xfr_input_stream: skipped unsupported record #%d %{recordwire}", data->record_index, record); data->record_index++; continue; } #if DEBUG_XFR_INPUT_STREAM log_debug("xfr_input_stream: #%u %{recordwire}", data->record_index, record); #endif u8 *ptr = record + dnsname_len(record); u16 rtype = GET_U16_AT(*ptr); switch(rtype) { case TYPE_SOA: { /* handle SOA case */ if(!dnsname_equals(record, data->origin)) { data->eos = TRUE; return_value = ERROR; // OWNER OF SOA RECORD SHOULD BE ORIGIN (protocol error) return return_value; } ptr += 10; /* type class ttl rdata_size */ ptr += dnsname_len(ptr); ptr += dnsname_len(ptr); u32 soa_serial = ntohl(GET_U32_AT(*ptr)); if(data->xfr_mode == TYPE_ANY) { if(data->record_index == 1) { /* * This is an IXFR, the first record is not sent up */ data->xfr_mode = TYPE_IXFR; } else { output_stream_write(&data->pipe_stream_output, data->first_soa_record, data->first_soa_record_size); data->xfr_mode = TYPE_AXFR; } } if(soa_serial == data->last_serial) { // the SOA serial has the same value as the last record we expect // if it's an AXFR or this is the second time it happens on an IXFR, then it's then end of the stream if(data->xfr_mode == TYPE_AXFR || ((data->xfr_mode == TYPE_IXFR) && data->ixfr_mark)) { return_value = SUCCESS; /* * The last record of an AXFR must be written, * the last record of an IXFR must not. */ if(data->xfr_mode == TYPE_AXFR) { #if DEBUG_XFR_INPUT_STREAM log_debug("xfr_input_stream: #%u %{recordwire} ; (AXFR END)", data->record_index, record); #endif return_value = output_stream_write(&data->pipe_stream_output, record, record_len); } #if DEBUG_XFR_INPUT_STREAM else { log_debug("xfr_input_stream: #%u %{recordwire} ; (IXFR END)", data->record_index, record); } #endif // done data->eos = TRUE; return return_value; // reached the end } // IXFR needs to find the mark twice #if DEBUG_XFR_INPUT_STREAM log_debug("xfr_input_stream: #%u %{recordwire} ; (IXFR LAST)", data->record_index, record); #endif data->ixfr_mark = TRUE; } break; } case TYPE_IXFR: case TYPE_AXFR: case TYPE_OPT: case TYPE_ANY: return INVALID_PROTOCOL; default: if(data->record_index == 1) { // special case to detect an AXFR returned by an IXFR query if(data->xfr_mode == TYPE_ANY) { data->xfr_mode = TYPE_AXFR; if(FAIL(return_value = output_stream_write(&data->pipe_stream_output, data->first_soa_record, data->first_soa_record_size))) { return return_value; } } else { return_value = ERROR; return return_value; // invalid status } } break; } #if DEBUG_XFR_INPUT_STREAM log_debug("xfr_input_stream: >%u %{recordwire}", data->record_index, record); #endif if(FAIL(return_value = output_stream_write(&data->pipe_stream_output, record, record_len))) { data->eos = TRUE; break; } if(return_value != record_len) { return UNEXPECTED_EOF; } data->record_index++; } return return_value; }
ya_result output_stream_write_u16(output_stream* os, u16 value) { return output_stream_write(os, (u8*) & value, 2); }
ya_result output_stream_write_dnsname(output_stream* os, const u8 *name) { u32 len = dnsname_len(name); return output_stream_write(os, name, len); }
ya_result output_stream_decode_base16(output_stream* os, const char * string, u32 length) { const char *string_start = string; u32 needle = 0; ya_result return_code = OK; char buffer[64]; u8 buffer_bin[32]; /* ------------------------------------------------------------ */ while(length-- > 0) { char c = *string++; if(isspace(c)) { continue; } buffer[needle++] = c; if(needle == sizeof (buffer)) { if(FAIL(return_code = base16_decode(buffer, needle, buffer_bin))) { return return_code; } if(FAIL(return_code = output_stream_write(os, buffer_bin, return_code))) { return return_code; } needle = 0; } } if(needle > 0) { if((needle & 1) != 0) { return PARSEB16_ERROR; } if(FAIL(return_code = base16_decode(buffer, needle, buffer_bin))) { return return_code; } if(FAIL(return_code = output_stream_write(os, buffer_bin, return_code))) { return return_code; } } /* return the number of bytes read, instead of the last write size * this way something can be done about the input. * * alternatively we could just return "success" */ return string - string_start; }