static void f_parse_headers( INT32 args ) { struct mapping *headermap; struct pike_string *headers; unsigned char *ptr; int len = 0, parsed = 0; get_all_args("Caudium.parse_headers", args, "%S", &headers); headermap = allocate_mapping(1); ptr = (unsigned char *)headers->str; len = headers->len; /* * FIXME: * What do we do if memory allocation fails halfway through * allocating a new mapping? Should we return that half-finished * mapping or rather return NULL? For now it's the former case. * /Grendel * * If memory allocation fails, just bail out with error() */ while(len > 0 && (parsed = get_next_header(ptr, len, headermap)) >= 0 ) { ptr += parsed; len -= parsed; } if(parsed == -1) { Pike_error("Caudium.parse_headers(): Out of memory while parsing.\n"); } pop_n_elems(args); push_mapping(headermap); }
// Validate a MAP packet. // // If the require_checksum argument is true, then the packet must contain a (valid) checksum // in the outermost encapsulation to be considered valid. // If the remove_checksums argument is true, then any checksums present will be removed // once validated. (Note that the process aborts after encountering the first packet error.) bool MAP::MAPPacket::validate(HeaderOffset_t headerOffset, bool require_checksum, bool remove_checksums){ // Make sure packet includes at least an initial header // Make sure packet includes an outermost checksum, if requested. Data_t* header = get_header(headerOffset); if( header == NULL || ( require_checksum && !get_checksumPresent(*header) ) ) return false; DEBUGprint_MAP("MPPval: cap=%d, size=%d\n", get_capacity(), get_size()); // Validate (possibly nested) MAP header structure. // This requires a pass through the entire header structure. // Some processing time could perhaps be saved by using the same // pass to feed all the headers through the checksum engine, // especially if the packet data is stored in something slower // than RAM. Data_t* data_ptr = get_data(header); if(data_ptr == NULL) return false; // Stop point Data_t *stop_ptr = back(); // Stop at actual data (no more MAP headers). while(header != NULL){ // If header indicates a checksum, validate it. if(get_checksumPresent(*header)){ DEBUGprint_MAP("MPPval: val crc\n"); // Validate the checksum if(! validateChecksum(header, stop_ptr)) return false; // Encapsulated data is now one checksum back. stop_ptr -= MAP::ChecksumLength; if(remove_checksums){ *header = MAP::set_checksumPresent(*header, false); DEBUGprint_MAP("MPPval: rem crc\n"); } } // Next header header = get_next_header(header); } // If requested, cut off all checksums. if(remove_checksums){ // Set the packet size such that the checksums (at the end) are all removed. set_size(stop_ptr - front()); // Try to eliminate excess capacity //set_capacity(stop_ptr - front()); } // Checksums (if any) were all valid. return true; }