Codebase list dnsviz / e6d2c66
Try ordereddict library as backup to built-in For python 2.6 support Casey Deccio 7 years ago
10 changed file(s) with 116 addition(s) and 66 deletion(s). Raw diff Collapse all Expand all
2121 from __future__ import unicode_literals
2222
2323 import cgi
24 import collections
2524 import datetime
25
26 # minimal support for python2.6
27 try:
28 from collections import OrderedDict
29 except ImportError:
30 from ordereddict import OrderedDict
2631
2732 import dns.dnssec
2833
104109 del self.servers_clients[(server, client)]
105110
106111 def serialize(self, consolidate_clients=False, html_format=False):
107 d = collections.OrderedDict()
112 d = OrderedDict()
108113
109114 if html_format:
110115 d['description'] = self.html_description
2626
2727 from __future__ import unicode_literals
2828
29 import collections
3029 import errno
3130 import logging
31
32 # minimal support for python2.6
33 try:
34 from collections import OrderedDict
35 except ImportError:
36 from ordereddict import OrderedDict
3237
3338 import dns.flags, dns.rdataclass, dns.rdatatype
3439
462467
463468 def _serialize_status_simple(self, response_info_list, processed):
464469 tup = []
465 cname_info_map = collections.OrderedDict()
470 cname_info_map = OrderedDict()
466471
467472 # just get the first one since the names are all supposed to be the
468473 # same
22792284 self.response_component_status = response_component_status
22802285
22812286 def _serialize_rrset_info(self, rrset_info, consolidate_clients=False, show_servers=True, loglevel=logging.DEBUG, html_format=False):
2282 d = collections.OrderedDict()
2287 d = OrderedDict()
22832288
22842289 rrsig_list = []
22852290 if self.rrsig_status[rrset_info]:
23012306 if dname_serialized:
23022307 dname_list.append(dname_serialized)
23032308
2304 wildcard_proof_list = collections.OrderedDict()
2309 wildcard_proof_list = OrderedDict()
23052310 if rrset_info.wildcard_info:
23062311 wildcard_names = list(rrset_info.wildcard_info.keys())
23072312 wildcard_names.sort()
23652370 return d
23662371
23672372 def _serialize_negative_response_info(self, neg_response_info, neg_status, warnings, errors, consolidate_clients=False, loglevel=logging.DEBUG, html_format=False):
2368 d = collections.OrderedDict()
2373 d = OrderedDict()
23692374
23702375 proof_list = []
23712376 for nsec_status in neg_status[neg_response_info]:
24192424 return d
24202425
24212426 def _serialize_query_status(self, query, consolidate_clients=False, loglevel=logging.DEBUG, html_format=False):
2422 d = collections.OrderedDict()
2427 d = OrderedDict()
24232428 d['answer'] = []
24242429 d['nxdomain'] = []
24252430 d['nodata'] = []
24822487 return d
24832488
24842489 def _serialize_delegation_status(self, rdtype, consolidate_clients=False, loglevel=logging.DEBUG, html_format=False):
2485 d = collections.OrderedDict()
2490 d = OrderedDict()
24862491
24872492 dss = list(self.ds_status_by_ds[rdtype].keys())
24882493 d['ds'] = []
25312536 return d
25322537
25332538 def _serialize_zone_status(self, consolidate_clients=False, loglevel=logging.DEBUG, html_format=False):
2534 d = collections.OrderedDict()
2539 d = OrderedDict()
25352540
25362541 if loglevel <= logging.DEBUG:
25372542 glue_ip_mapping = self.get_glue_ip_mapping()
25382543 auth_ns_ip_mapping = self.get_auth_ns_ip_mapping()
2539 d['servers'] = collections.OrderedDict()
2544 d['servers'] = OrderedDict()
25402545 names = list(self.get_ns_names())
25412546 names.sort()
25422547 for name in names:
25432548 name_str = lb2s(name.canonicalize().to_text())
2544 d['servers'][name_str] = collections.OrderedDict()
2549 d['servers'][name_str] = OrderedDict()
25452550 if name in glue_ip_mapping and glue_ip_mapping[name]:
25462551 servers = list(glue_ip_mapping[name])
25472552 servers.sort()
25692574 name_str = lb2s(name.canonicalize().to_text())
25702575 servers = stealth_mapping[name]
25712576 servers.sort()
2572 d['servers'][name_str] = collections.OrderedDict((
2577 d['servers'][name_str] = OrderedDict((
25732578 ('stealth', servers),
25742579 ))
25752580
25862591
25872592 def serialize_status(self, d=None, is_dlv=False, loglevel=logging.DEBUG, ancestry_only=False, level=RDTYPES_ALL, trace=None, follow_mx=True, html_format=False):
25882593 if d is None:
2589 d = collections.OrderedDict()
2594 d = OrderedDict()
25902595
25912596 if trace is None:
25922597 trace = []
26492654
26502655 erroneous_status = self.status not in (Status.NAME_STATUS_NOERROR, Status.NAME_STATUS_NXDOMAIN)
26512656
2652 d[name_str] = collections.OrderedDict()
2657 d[name_str] = OrderedDict()
26532658 if loglevel <= logging.INFO or erroneous_status:
26542659 d[name_str]['status'] = Status.name_status_mapping[self.status]
26552660
2656 d[name_str]['queries'] = collections.OrderedDict()
2661 d[name_str]['queries'] = OrderedDict()
26572662 query_keys = list(self.queries.keys())
26582663 query_keys.sort()
26592664 required_rdtypes = self._rdtypes_for_analysis_level(level)
2626
2727 from __future__ import unicode_literals
2828
29 import collections
3029 import datetime
3130 import logging
3231 import random
3635 import threading
3736 import time
3837 import uuid
38
39 # minimal support for python2.6
40 try:
41 from collections import OrderedDict
42 except ImportError:
43 from ordereddict import OrderedDict
3944
4045 import dns.flags, dns.name, dns.rdataclass, dns.rdatatype, dns.resolver
4146
710715
711716 def serialize(self, d=None, meta_only=False, trace=None):
712717 if d is None:
713 d = collections.OrderedDict()
718 d = OrderedDict()
714719
715720 if trace is None:
716721 trace = []
738743 clients_ipv6 = list(self.clients_ipv6)
739744 clients_ipv6.sort()
740745
741 d[name_str] = collections.OrderedDict()
746 d[name_str] = OrderedDict()
742747 d[name_str]['type'] = analysis_types[self.analysis_type]
743748 d[name_str]['stub'] = self.stub
744749 d[name_str]['analysis_start'] = fmt.datetime_to_str(self.analysis_start)
767772
768773 def _serialize_related(self, d, meta_only):
769774 if self._auth_ns_ip_mapping:
770 d['auth_ns_ip_mapping'] = collections.OrderedDict()
775 d['auth_ns_ip_mapping'] = OrderedDict()
771776 ns_names = list(self._auth_ns_ip_mapping.keys())
772777 ns_names.sort()
773778 for name in ns_names:
12191224 rdtypes.extend([dns.rdatatype.A, dns.rdatatype.AAAA])
12201225
12211226 # remove duplicates
1222 rdtypes = list(collections.OrderedDict.fromkeys(rdtypes))
1227 rdtypes = list(OrderedDict.fromkeys(rdtypes))
12231228
12241229 return rdtypes
12251230
17451750 if not parent_auth_servers:
17461751 return False
17471752
1748 servers_queried = collections.OrderedDict(((dns.rdatatype.NS, set()),))
1753 servers_queried = OrderedDict(((dns.rdatatype.NS, set()),))
17491754 referral_queries = {}
17501755
17511756 try:
2828
2929 import base64
3030 import cgi
31 import collections
3231 import datetime
3332 import logging
33
34 # minimal support for python2.6
35 try:
36 from collections import OrderedDict
37 except ImportError:
38 from ordereddict import OrderedDict
3439
3540 import dns.name, dns.rdatatype
3641
227232 return 'RRSIG covering %s/%s' % (fmt.humanize_name(self.rrset.rrset.name), dns.rdatatype.to_text(self.rrset.rrset.rdtype))
228233
229234 def serialize(self, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
230 d = collections.OrderedDict()
235 d = OrderedDict()
231236
232237 erroneous_status = self.validation_status not in (RRSIG_STATUS_VALID, RRSIG_STATUS_INDETERMINATE_NO_DNSKEY, RRSIG_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM)
233238
366371 return '%s record(s) corresponding to DNSKEY for %s (algorithm %d (%s), key tag %d)' % (dns.rdatatype.to_text(self.ds_meta.rrset.rdtype), fmt.humanize_name(self.ds_meta.rrset.name), self.ds.algorithm, fmt.DNSKEY_ALGORITHMS.get(self.ds.algorithm, self.ds.algorithm), self.ds.key_tag)
367372
368373 def serialize(self, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
369 d = collections.OrderedDict()
374 d = OrderedDict()
370375
371376 erroneous_status = self.validation_status not in (DS_STATUS_VALID, DS_STATUS_INDETERMINATE_NO_DNSKEY, DS_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM)
372377
510515 return 'NSEC record(s) proving the non-existence (NXDOMAIN) of %s' % (fmt.humanize_name(self.qname))
511516
512517 def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
513 d = collections.OrderedDict()
518 d = OrderedDict()
514519
515520 nsec_list = []
516521 for nsec_rrset in self.nsec_set_info.rrsets.values():
547552 qname, nsec_names = list(self.nsec_names_covering_qname.items())[0]
548553 nsec_name = list(nsec_names)[0]
549554 nsec_rr = self.nsec_set_info.rrsets[nsec_name].rrset[0]
550 d['sname_covering'] = collections.OrderedDict((
555 d['sname_covering'] = OrderedDict((
551556 ('covered_name', formatter(lb2s(qname.canonicalize().to_text()))),
552557 ('nsec_owner', formatter(lb2s(nsec_name.canonicalize().to_text()))),
553558 ('nsec_next', formatter(lb2s(nsec_rr.next.canonicalize().to_text())))
556561 wildcard, nsec_names = list(self.nsec_names_covering_wildcard.items())[0]
557562 nsec_name = list(nsec_names)[0]
558563 nsec_rr = self.nsec_set_info.rrsets[nsec_name].rrset[0]
559 d['wildcard_covering'] = collections.OrderedDict((
564 d['wildcard_covering'] = OrderedDict((
560565 ('covered_name', formatter(lb2s(wildcard.canonicalize().to_text()))),
561566 ('nsec_owner', formatter(lb2s(nsec_name.canonicalize().to_text()))),
562567 ('nsec_next', formatter(lb2s(nsec_rr.next.canonicalize().to_text())))
761766 self.nsec_set_info = nsec_set_info.project(*list(nsec_set_info.rrsets))
762767
763768 def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
764 d = collections.OrderedDict()
769 d = OrderedDict()
765770
766771 nsec_list = []
767772 for nsec_rrset in self.nsec_set_info.rrsets.values():
801806 qname, nsec_names = list(self.nsec_names_covering_qname.items())[0]
802807 nsec_name = list(nsec_names)[0]
803808 nsec_rr = self.nsec_set_info.rrsets[nsec_name].rrset[0]
804 d['sname_covering'] = collections.OrderedDict((
809 d['sname_covering'] = OrderedDict((
805810 ('covered_name', formatter(lb2s(qname.canonicalize().to_text()))),
806811 ('nsec_owner', formatter(lb2s(nsec_name.canonicalize().to_text()))),
807812 ('nsec_next', formatter(lb2s(nsec_rr.next.canonicalize().to_text())))
974979 self.errors.append(Errors.InvalidNSEC3Hash(name=fmt.format_nsec3_name(name), nsec3_hash=lb2s(base32.b32encode(self.nsec_set_info.rrsets[name].rrset[0].next))))
975980
976981 def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
977 d = collections.OrderedDict()
982 d = OrderedDict()
978983
979984 nsec3_list = []
980985 for nsec_rrset in self.nsec_set_info.rrsets.values():
10301035 qname, nsec_names = list(self.nsec_names_covering_qname.items())[0]
10311036 nsec_name = list(nsec_names)[0]
10321037 next_name = self.nsec_set_info.name_for_nsec3_next(nsec_name)
1033 d['next_closest_encloser_covering'] = collections.OrderedDict((
1038 d['next_closest_encloser_covering'] = OrderedDict((
10341039 ('covered_name', formatter(fmt.format_nsec3_name(qname))),
10351040 ('nsec_owner', formatter(fmt.format_nsec3_name(nsec_name))),
10361041 ('nsec_next', formatter(fmt.format_nsec3_name(next_name))),
10471052 wildcard, nsec_names = list(self.nsec_names_covering_wildcard.items())[0]
10481053 nsec_name = list(nsec_names)[0]
10491054 next_name = self.nsec_set_info.name_for_nsec3_next(nsec_name)
1050 d['wildcard_covering'] = collections.OrderedDict((
1055 d['wildcard_covering'] = OrderedDict((
10511056 ('covered_name', formatter(fmt.format_nsec3_name(wildcard))),
10521057 ('nsec3_owner', formatter(fmt.format_nsec3_name(nsec_name))),
10531058 ('nsec3_next', formatter(fmt.format_nsec3_name(next_name))),
13251330 self.errors.append(Errors.InvalidNSEC3Hash(name=fmt.format_nsec3_name(name), nsec3_hash=lb2s(base32.b32encode(self.nsec_set_info.rrsets[name].rrset[0].next))))
13261331
13271332 def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
1328 d = collections.OrderedDict()
1333 d = OrderedDict()
13291334
13301335 nsec3_list = []
13311336 for nsec_rrset in self.nsec_set_info.rrsets.values():
13871392 qname, nsec_names = list(self.nsec_names_covering_qname.items())[0]
13881393 nsec_name = list(nsec_names)[0]
13891394 next_name = self.nsec_set_info.name_for_nsec3_next(nsec_name)
1390 d['next_closest_encloser_covering'] = collections.OrderedDict((
1395 d['next_closest_encloser_covering'] = OrderedDict((
13911396 ('covered_name', formatter(fmt.format_nsec3_name(qname))),
13921397 ('nsec3_owner', formatter(fmt.format_nsec3_name(nsec_name))),
13931398 ('nsec3_next', formatter(fmt.format_nsec3_name(next_name))),
14621467
14631468 def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
14641469 values = []
1465 d = collections.OrderedDict()
1470 d = OrderedDict()
14661471
14671472 dname_serialized = None
14681473 if rrset_info_serializer is not None:
2222 from __future__ import unicode_literals
2323
2424 import codecs
25 import collections
2625 import getopt
2726 import io
2827 import json
3029 import os
3130 import re
3231 import sys
32
33 # minimal support for python2.6
34 try:
35 from collections import OrderedDict
36 except ImportError:
37 from ordereddict import OrderedDict
3338
3439 import dns.exception, dns.name
3540
315320 if not name_objs:
316321 sys.exit(4)
317322
318 d = collections.OrderedDict()
323 d = OrderedDict()
319324 for name_obj in name_objs:
320325 name_obj.populate_status(trusted_keys)
321326
2222 from __future__ import unicode_literals
2323
2424 import atexit
25 import collections
2625 import codecs
2726 import errno
2827 import getopt
4342 import tempfile
4443 import threading
4544 import time
45
46 # minimal support for python2.6
47 try:
48 from collections import OrderedDict
49 except ImportError:
50 from ordereddict import OrderedDict
4651
4752 # python3/python2 dual compatibility
4853 try:
10541059 sys.exit(3)
10551060
10561061 def _flush(name_obj):
1057 d = collections.OrderedDict()
1062 d = OrderedDict()
10581063 name_obj.serialize(d)
10591064 s = json.dumps(d, **kwargs)
10601065 lindex = s.index('{')
10981103 if not name_objs:
10991104 sys.exit(4)
11001105
1101 d = collections.OrderedDict()
1106 d = OrderedDict()
11021107 for name_obj in name_objs:
11031108 name_obj.serialize(d, meta_only)
11041109 d['_meta._dnsviz.'] = dnsviz_meta
2828
2929 import base64
3030 import bisect
31 import collections
3231 import errno
3332 import io
3433 import socket
3534 import struct
3635 import time
36
37 # minimal support for python2.6
38 try:
39 from collections import OrderedDict
40 except ImportError:
41 from ordereddict import OrderedDict
3742
3843 # python3/python2 dual compatibility
3944 try:
175180 def serialize(self):
176181 '''Return a serialized version of the query.'''
177182
178 d = collections.OrderedDict()
183 d = OrderedDict()
179184 d['time_elapsed'] = int(self.response_time * 1000)
180185 d['cause'] = retry_causes.get(self.cause, 'UNKNOWN')
181186 if self.cause_arg is not None:
10641069 return False
10651070
10661071 def serialize(self, meta_only=False):
1067 d = collections.OrderedDict((
1072 d = OrderedDict((
10681073 ('qname', lb2s(self.qname.to_text())),
10691074 ('qclass', dns.rdataclass.to_text(self.rdclass)),
10701075 ('qtype', dns.rdatatype.to_text(self.rdtype)),
10711076 ))
1072 d['options'] = collections.OrderedDict((
1077 d['options'] = OrderedDict((
10731078 ('flags', self.flags),
10741079 ))
10751080 if self.edns >= 0:
10831088 d['options']['edns_options'].append((o.otype, lb2s(base64.b64encode(s.getvalue()))))
10841089 d['options']['tcp'] = self.tcp
10851090
1086 d['responses'] = collections.OrderedDict()
1091 d['responses'] = OrderedDict()
10871092 servers = list(self.responses.keys())
10881093 servers.sort()
10891094 for server in servers:
1090 d['responses'][server] = collections.OrderedDict()
1095 d['responses'][server] = OrderedDict()
10911096 clients = list(self.responses[server].keys())
10921097 clients.sort()
10931098 for client in clients:
3030 import errno
3131 import cgi
3232 import codecs
33 import collections
3433 import datetime
3534 import hashlib
3635 import io
3837 import socket
3938 import struct
4039 import time
40
41 # minimal support for python2.6
42 try:
43 from collections import OrderedDict
44 except ImportError:
45 from ordereddict import OrderedDict
4146
4247 import dns.flags, dns.message, dns.rcode, dns.rdataclass, dns.rdatatype, dns.rrset
4348
453458 def serialize_meta(self):
454459 from . import query as Q
455460
456 d = collections.OrderedDict()
461 d = OrderedDict()
457462
458463 # populate history, if not already populated
459464 if self.effective_flags is None:
469474 d['rcode'] = dns.rcode.to_text(self.message.rcode())
470475 if self.message.edns >= 0:
471476 d['edns_version'] = self.message.edns
472 d['answer'] = collections.OrderedDict((
477 d['answer'] = OrderedDict((
473478 ('count', self.section_rr_count(self.message.answer)),
474479 ('digest', self.section_digest(self.message.answer)),
475480 ))
476 d['authority'] = collections.OrderedDict((
481 d['authority'] = OrderedDict((
477482 ('count', self.section_rr_count(self.message.authority)),
478483 ('digest', self.section_digest(self.message.authority)),
479484 ))
480 d['additional'] = collections.OrderedDict((
485 d['additional'] = OrderedDict((
481486 ('count', self.section_rr_count(self.message.additional)),
482487 ('digest', self.section_digest(self.message.additional)),
483488 ))
494499 d['retries'] = self.retries()
495500 if self.history:
496501 d['cumulative_response_time'] = int(self.total_response_time() * 1000)
497 d['effective_query_options'] = collections.OrderedDict((
502 d['effective_query_options'] = OrderedDict((
498503 ('flags', self.effective_flags),
499504 ('edns_version', self.effective_edns),
500505 ('edns_max_udp_payload', self.effective_edns_max_udp_payload),
508513 d['effective_query_options']['tcp'] = self.effective_tcp
509514
510515 if self.responsive_cause_index is not None:
511 d['responsiveness_impediment'] = collections.OrderedDict((
516 d['responsiveness_impediment'] = OrderedDict((
512517 ('cause', Q.retry_causes[self.history[self.responsive_cause_index].cause]),
513518 ('action', Q.retry_actions[self.history[self.responsive_cause_index].action])
514519 ))
518523 def serialize(self):
519524 from . import query as Q
520525
521 d = collections.OrderedDict()
526 d = OrderedDict()
522527 if self.message is None:
523528 d['message'] = None
524529 d['error'] = Q.response_errors[self.error]
744749 (self.warnings and loglevel <= logging.WARNING) or \
745750 (self.errors and loglevel <= logging.ERROR)
746751
747 d = collections.OrderedDict()
752 d = OrderedDict()
748753
749754 if html_format:
750755 formatter = lambda x: cgi.escape(x, True)
924929 return rrsig_canonicalized_wire + rrset_canonicalized_wire
925930
926931 def serialize(self, consolidate_clients=True, show_servers=True, loglevel=logging.DEBUG, html_format=False):
927 d = collections.OrderedDict()
932 d = OrderedDict()
928933
929934 if html_format:
930935 formatter = lambda x: cgi.escape(x, True)
2323 import base64
2424 import bisect
2525 import codecs
26 import collections
2726 import errno
2827 import fcntl
2928 import json
3635 import struct
3736 import threading
3837 import time
38
39 # minimal support for python2.6
40 try:
41 from collections import OrderedDict
42 except ImportError:
43 from ordereddict import OrderedDict
3944
4045 # python3/python2 dual compatibility
4146 try:
9196 self.end_time = None
9297
9398 def serialize_request(self):
94 d = collections.OrderedDict()
99 d = OrderedDict()
95100 d['req'] = lb2s(base64.b64encode(self.req))
96101 d['dst'] = self.dst
97102 d['dport'] = self.dport
162167 return cls(req, dst, tcp, timeout, dport, src, sport)
163168
164169 def serialize_response(self):
165 d = collections.OrderedDict()
170 d = OrderedDict()
166171 if self.res is not None:
167172 d['res'] = lb2s(base64.b64encode(self.res))
168173 else:
2828
2929 import codecs
3030 import cgi
31 import collections
3231 import errno
3332 import io
3433 import json
3635 import re
3736 import sys
3837 import xml.dom.minidom
38
39 # minimal support for python2.6
40 try:
41 from collections import OrderedDict
42 except ImportError:
43 from ordereddict import OrderedDict
3944
4045 import dns.name, dns.rdtypes, dns.rdatatype, dns.dnssec
4146
7580 self.key_tag = key_tag
7681
7782 def serialize(self):
78 d = collections.OrderedDict()
83 d = OrderedDict()
7984 d['flags'] = None
8085 d['protocol'] = None
8186 d['algorithm'] = self.algorithm
9398 self.servers_clients = servers_clients
9499
95100 def serialize(self, consolidate_clients, html_format=False):
96 d = collections.OrderedDict()
101 d = OrderedDict()
97102
98103 if html_format:
99104 formatter = lambda x: cgi.escape(x, True)
575580 self.node_reverse_mapping[zone_obj] = top_name
576581
577582 consolidate_clients = zone_obj.single_client()
578 zone_serialized = collections.OrderedDict()
583 zone_serialized = OrderedDict()
579584 zone_serialized['description'] = '%s zone' % (zone_obj)
580585 if zone_obj.zone_errors:
581586 zone_serialized['errors'] = [e.serialize(consolidate_clients=consolidate_clients, html_format=True) for e in zone_obj.zone_errors]
811816
812817 consolidate_clients = name_obj.single_client()
813818
814 errors_serialized = collections.OrderedDict()
819 errors_serialized = OrderedDict()
815820
816821 errors_serialized['description'] = '%s %s/%s' % (description, fmt.humanize_name(name), dns.rdatatype.to_text(rdtype))
817822 errors_serialized[category] = [e.serialize(consolidate_clients=consolidate_clients, html_format=True) for e in errors_list]
14091414 line_style = 'dashed'
14101415
14111416 consolidate_clients = name_obj.single_client()
1412 del_serialized = collections.OrderedDict()
1417 del_serialized = OrderedDict()
14131418 del_serialized['description'] = 'Delegation from %s to %s' % (lb2s(name_obj.parent.name.to_text()), lb2s(name_obj.name.to_text()))
14141419 del_serialized['status'] = Status.delegation_status_mapping[name_obj.delegation_status[rdtype]]
14151420