
Hi, I decided to give it a shot in implementing full DNS/DNSSEC resolution support for Tor, here's the branch: https://github.com/hiviah/tor ATM the biggest limitation is that reply DNS packet must fit in a single cell (i.e. max size is RELAY_PAYLOAD_SIZE). How it's implemented: There's new command SOCKS_COMMAND_RESOLVE_FULL for SOCKS interface and new cells RELAY_COMMAND_RESOLVE(D)_FULL. The RESOLVE_FULL cell contains query string and RR-type, RESOLVED_FULL just the DNS packet in wire format. Resolving is implemented via libunbound on the relay's side, ldns parses packet on client's side. The tor-resolve now uses the new SOCKS command and accepts -t parameter with RR-type (numeric, default 1 - RR-type 'A'), e.g.: ./src/tools/tor-resolve -t 28 lupa.cz localhost:10050 Packet size: 319 Flags: qr: 1, aa: 0, tc: 0, rd: 1, cd: 0, ra: 1, ad: 1 -- Rcode: NOERROR -- Opcode: QUERY -- Question section lupa.cz. IN AAAA -- Answer section lupa.cz. 600 IN AAAA 2001:67c:68::7b lupa.cz. 600 IN RRSIG AAAA 5 2 600 20121022235305 20111023235305 8130 lupa.cz. wFdVqKCEh4Nmac3v5K9y6HT+aIBAtF4Q9QIqHjlAl/ljp4m5TKkgKCF083zFTMh0LqfwdODfQdSNTKAwO55hyw== -- Authority section lupa.cz. 600 IN NS ns.iinfo.cz. lupa.cz. 600 IN NS ns6.adminit.cz. lupa.cz. 600 IN RRSIG NS 5 2 600 20121022235305 20111023235305 8130 lupa.cz. SpqkpBlK1dzrfACHh3yfUp01Vr/w9qzVYQms4RDXNQZW1Hwr5WYMHIuGrFEgOOrjyg1vB01HENXJf4i2ISx51g== -- Additional section Other implementation notes: - some checks like whether private address is resolved are missing (also a whitelist of allowed RR-types might be implemented) - in the SOCKS5 request, RR-type is hacked onto port number - in SOCKS5 reply, high byte of length is hacked onto SOCKS5 reserved byte - libunbound supports async resolving, for now synchronous is used - there are more details, grep FIXDNS in code - Makefile.am's have -lldns and -lunbound hardwired - new code may not be pretty at some places (getting to know Tor code) Also, this seems to be a bug in relay.c:connection_edge_process_relay_cell_not_open(), the RELAY_COMMAND_RESOLVED case: answer_len = cell->payload[RELAY_HEADER_SIZE+1]; if (rh->length < 2 || answer_len+2>rh->length) {...} Payload is accessed before checking bounds. Ondrej