bugfix: add null terminators for packing SOA records
This commit is contained in:
		
							parent
							
								
									98187043ec
								
							
						
					
					
						commit
						a538fa4f58
					
				| @ -35,7 +35,7 @@ var hexdump = require('hexdump.js').hexdump; | |||||||
| function testJsonAsync(nb) { | function testJsonAsync(nb) { | ||||||
|   var packet = dnsjs.write(JSON.parse(nb.toString('ascii'))); |   var packet = dnsjs.write(JSON.parse(nb.toString('ascii'))); | ||||||
|   var str = hexdump(packet); |   var str = hexdump(packet); | ||||||
|   console.log(str); |   console.info(str); | ||||||
|   var json = dnsjs.parse(packet); |   var json = dnsjs.parse(packet); | ||||||
|   if (json.error) { |   if (json.error) { | ||||||
|     console.error(json); |     console.error(json); | ||||||
| @ -43,7 +43,7 @@ function testJsonAsync(nb) { | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   console.log("[OK] JSON -> binary -> JSON"); |   console.info("[OK] JSON -> binary -> JSON"); | ||||||
| 
 | 
 | ||||||
|   if (!outname) { |   if (!outname) { | ||||||
|     console.warn(''); |     console.warn(''); | ||||||
| @ -54,7 +54,7 @@ function testJsonAsync(nb) { | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   fs.writeFileSync(path.basename(filename).replace(path.extname(filename), '.bin'), packet, null); |   fs.writeFileSync(outname, packet, null); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function testBinAsync(nb) { | function testBinAsync(nb) { | ||||||
| @ -66,6 +66,8 @@ function testBinAsync(nb) { | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   var bin2 = dnsjs.write(json); |   var bin2 = dnsjs.write(json); | ||||||
|  |   //var debugname = outname || path.basename(filename);
 | ||||||
|  |   //fs.writeFileSync(debugname.replace(path.extname(debugname), '.bin'), bin2, null);
 | ||||||
|   var json2 = dnsjs.parse(bin2); |   var json2 = dnsjs.parse(bin2); | ||||||
|   if (json2.error) { |   if (json2.error) { | ||||||
|     console.error(json2); |     console.error(json2); | ||||||
| @ -86,12 +88,22 @@ function testBinAsync(nb) { | |||||||
|     .replace(/,"cpcount":\d+/, '') |     .replace(/,"cpcount":\d+/, '') | ||||||
|   ); |   ); | ||||||
|   //json2 = JSON.parse(JSON.stringify(json2));
 |   //json2 = JSON.parse(JSON.stringify(json2));
 | ||||||
|   //console.log(json);
 |   try { | ||||||
|   //console.log(json2);
 |  | ||||||
|     assert.deepEqual(json, json2); |     assert.deepEqual(json, json2); | ||||||
|  |   } catch(e) { | ||||||
|  |     console.error(''); | ||||||
|  |     console.error('Original'); | ||||||
|  |     console.error(JSON.stringify(json, null, 2)); | ||||||
|  |     console.error(''); | ||||||
|  |     console.error('Converted'); | ||||||
|  |     console.error(JSON.stringify(json2, null, 2)); | ||||||
|  |     console.error(''); | ||||||
|  |     process.exit(422); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   console.log("[OK] binary -> JSON -> binary -> JSON"); |   console.info("[OK] binary -> JSON -> binary -> JSON"); | ||||||
|   console.log("(compression pointer support needs to be improved in order to support direct bin -> JSON -> bin testing)"); |   console.warn("(compression pointer support needs to be improved in order to support direct bin -> JSON -> bin testing)"); | ||||||
| 
 | 
 | ||||||
|   if (!outname) { |   if (!outname) { | ||||||
|     console.warn(''); |     console.warn(''); | ||||||
| @ -102,7 +114,7 @@ function testBinAsync(nb) { | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   fs.writeFileSync(path.basename(filename).replace(path.extname(filename), '.json'), JSON.stringify(json, null, 2), null); |   fs.writeFileSync(outname, JSON.stringify(json, null, 2), null); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| if ('json' === extname) { | if ('json' === extname) { | ||||||
|  | |||||||
| @ -46,6 +46,10 @@ exports.DNS_UNPACK_LABELS = function (ui8, ptr, q) { | |||||||
| 
 | 
 | ||||||
|     //str.length = 0; // fast empty array
 |     //str.length = 0; // fast empty array
 | ||||||
|     if (ui8.byteLength - total < len) { |     if (ui8.byteLength - total < len) { | ||||||
|  |       //console.error('-1', ui8[total - 1]);
 | ||||||
|  |       //console.error(' 0', ui8[total]);
 | ||||||
|  |       //console.error(' 1', ui8[total + 1]);
 | ||||||
|  |       //console.error(' 1', ui8[total + 2]);
 | ||||||
|       throw new Error( |       throw new Error( | ||||||
|         "Expected a string of length " + len |         "Expected a string of length " + len | ||||||
|           + " but packet itself has " + (ui8.byteLength - total) + " bytes remaining" |           + " but packet itself has " + (ui8.byteLength - total) + " bytes remaining" | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| (function (exports) { | (function (exports) { | ||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
|  | // http://www.zytrax.com/books/dns/ch8/soa.html
 | ||||||
|  | 
 | ||||||
| // Value              Meaning/Use
 | // Value              Meaning/Use
 | ||||||
| // Primary NS         Variable length. The name of the Primary Master for the domain. May be a label, pointer, or any combination
 | // Primary NS         Variable length. The name of the Primary Master for the domain. May be a label, pointer, or any combination
 | ||||||
| // Admin MB           Variable length. The administrator's mailbox. May be a label, pointer, or any combination
 | // Admin MB           Variable length. The administrator's mailbox. May be a label, pointer, or any combination
 | ||||||
| @ -10,8 +12,6 @@ | |||||||
| // Expiration Limit   Unsigned 32-bit integer
 | // Expiration Limit   Unsigned 32-bit integer
 | ||||||
| // Minimum TTL        Unsigned 32-bit integer
 | // Minimum TTL        Unsigned 32-bit integer
 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | ||||||
|   if(!record.name_server){ |   if(!record.name_server){ | ||||||
|     throw new Error("no name server for SOA record"); |     throw new Error("no name server for SOA record"); | ||||||
| @ -23,16 +23,16 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | |||||||
|     throw new Error("no serial number for SOA record"); |     throw new Error("no serial number for SOA record"); | ||||||
|   } |   } | ||||||
|   if(!record.ref){ |   if(!record.ref){ | ||||||
|     throw new Error("no serial number for SOA record"); |     throw new Error("no refresh for SOA record"); | ||||||
|   } |   } | ||||||
|   if(!record.ret){ |   if(!record.ret){ | ||||||
|     throw new Error("no serial number for SOA record"); |     throw new Error("no update retry for SOA record"); | ||||||
|   } |   } | ||||||
|   if(!record.ex){ |   if(!record.ex){ | ||||||
|     throw new Error("no serial number for SOA record"); |     throw new Error("no expiry for SOA record"); | ||||||
|   } |   } | ||||||
|   if(!record.nx){ |   if(!record.nx){ | ||||||
|     throw new Error("no serial number for SOA record"); |     throw new Error("no nxdomain for SOA record"); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   var soaLen = 20; // take into account sn, ref, ret, ex, and nx
 |   var soaLen = 20; // take into account sn, ref, ret, ex, and nx
 | ||||||
| @ -40,9 +40,10 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | |||||||
|   var rdLenIndex = total; |   var rdLenIndex = total; | ||||||
|   total += 2; // Save space for RDLENGTH
 |   total += 2; // Save space for RDLENGTH
 | ||||||
| 
 | 
 | ||||||
|  |   console.log('record.name_server', 1 + record.name_server.length, record.name_server); | ||||||
|   // pack name_server which is a sequence of labels
 |   // pack name_server which is a sequence of labels
 | ||||||
|   record.name_server.split('.').forEach(function (label) { |   record.name_server.split('.').forEach(function (label) { | ||||||
|     soaLen += 1 + label.length; |     soaLen += (1 + label.length); | ||||||
| 
 | 
 | ||||||
|     dv.setUint8(total, label.length, false); |     dv.setUint8(total, label.length, false); | ||||||
|     total += 1; |     total += 1; | ||||||
| @ -52,7 +53,12 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | |||||||
|       total += 1; |       total += 1; | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
|  |   // must be terminated by null when not using write null
 | ||||||
|  |   dv.setUint8(total, 0, false); | ||||||
|  |   total += 1; | ||||||
|  |   soaLen += 1; | ||||||
| 
 | 
 | ||||||
|  |   console.log('record.email_addr', 1 + record.email_addr.length, record.email_addr); | ||||||
|   // pack email address which is a sequence of labels
 |   // pack email address which is a sequence of labels
 | ||||||
|   record.email_addr.split('.').forEach(function (label) { |   record.email_addr.split('.').forEach(function (label) { | ||||||
|     soaLen += 1 + label.length; |     soaLen += 1 + label.length; | ||||||
| @ -65,6 +71,10 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | |||||||
|       total += 1; |       total += 1; | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
|  |   // must be terminated by null when not using write null
 | ||||||
|  |   dv.setUint8(total, 0, false); | ||||||
|  |   total += 1; | ||||||
|  |   soaLen += 1; | ||||||
| 
 | 
 | ||||||
|   // pack all 32-bit values
 |   // pack all 32-bit values
 | ||||||
|   dv.setUint32(total, parseInt(record.sn, 10), false); |   dv.setUint32(total, parseInt(record.sn, 10), false); | ||||||
| @ -79,6 +89,8 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { | |||||||
|   total+=4; |   total+=4; | ||||||
| 
 | 
 | ||||||
|   // RDLENGTH
 |   // RDLENGTH
 | ||||||
|  |   console.log('rdAt', rdLenIndex); | ||||||
|  |   console.log('soaLen (lables + 2 + 20)', soaLen); | ||||||
|   dv.setUint16(rdLenIndex, soaLen, false); |   dv.setUint16(rdLenIndex, soaLen, false); | ||||||
| 
 | 
 | ||||||
|   return total; |   return total; | ||||||
|  | |||||||
| @ -18,13 +18,17 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { | |||||||
|   var dv = new DataView(rdataAb); |   var dv = new DataView(rdataAb); | ||||||
| 
 | 
 | ||||||
|   // we need this information for this parser
 |   // we need this information for this parser
 | ||||||
|   var cpcount = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).cpcount; |   var labelInfo = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }); | ||||||
|   var offset = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).byteLength; |   var cpcount = labelInfo.cpcount; | ||||||
|   var labels = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).labels; |   var offset = labelInfo.byteLength; | ||||||
|  |   var labels = labelInfo.labels; | ||||||
| 
 | 
 | ||||||
|   // Primary NS
 |   // Primary NS
 | ||||||
|   record.name_server = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; |   record.name_server = labelInfo.name; | ||||||
| 
 | 
 | ||||||
|  |   // TODO delete this commented out code after some testing
 | ||||||
|  |   // (pretty sure it was unnecessary and it seemed to work on code with compression pointers just fine)
 | ||||||
|  |   /* | ||||||
|   // if there exists compression pointers in the rdata
 |   // if there exists compression pointers in the rdata
 | ||||||
|   if (cpcount > 0) { |   if (cpcount > 0) { | ||||||
|     // do something awesome with compression pointers to get the email address
 |     // do something awesome with compression pointers to get the email address
 | ||||||
| @ -33,7 +37,7 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { | |||||||
|     // then there will be a compression pointer to grab the longest label.
 |     // then there will be a compression pointer to grab the longest label.
 | ||||||
| 
 | 
 | ||||||
|     var start = 2; // start or email_addr. take into account compression pointer and address length
 |     var start = 2; // start or email_addr. take into account compression pointer and address length
 | ||||||
|     for(var i = 0; i < labels.length; i++){ |     for (var i = 0; i < labels.length; i += 1) { | ||||||
| 
 | 
 | ||||||
|       // increase start by the label length. the +1 is to take into account the next label size byte
 |       // increase start by the label length. the +1 is to take into account the next label size byte
 | ||||||
|       start = start + labels[i].length + 1; |       start = start + labels[i].length + 1; | ||||||
| @ -47,6 +51,9 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { | |||||||
| 
 | 
 | ||||||
|     record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; |     record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; | ||||||
|   } |   } | ||||||
|  |   */ | ||||||
|  |   record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; | ||||||
|  | 
 | ||||||
|   // Serial Number
 |   // Serial Number
 | ||||||
|   record.sn = dv.getUint32(dv.byteLength - 20, false); |   record.sn = dv.getUint32(dv.byteLength - 20, false); | ||||||
|   // Refresh Interval
 |   // Refresh Interval
 | ||||||
| @ -58,9 +65,7 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { | |||||||
|   // Minimum TTL
 |   // Minimum TTL
 | ||||||
|   record.nx = dv.getUint32(dv.byteLength - 4, false); |   record.nx = dv.getUint32(dv.byteLength - 4, false); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|   return record; |   return record; | ||||||
| 
 |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| }('undefined' !== typeof window ? window : exports)); | }('undefined' !== typeof window ? window : exports)); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user