Description of problem: After enabling BIND for IPv6 listening and setup some views with match-destination, AXFR and TCP queries are no longer working. Version-Release number of selected component (if applicable): bind-9.2.3 How reproducible: Always (note that I'm not subscribed to bind-bugs...so perhaps one of the maintainers here can forward this bug report). Steps to Reproduce: 1. Enable IPv6 listening 2. configurate at least one view 3. add a match-destination 4. try AXFR or TCP query Actual Results: Not working, NO log entry (note that match-client works). It looks like that match-destination has a bug in the view matcher on TCP connects if IPv6 is enabled. Expected Results: Working and in case of forbidden, a log entry. Additional info: # Configuration file named.conf: options { directory "/var/named"; listen-on-v6 { any; }; }; controls { inet 127.0.0.1 allow { any; } keys { "rndckey"; }; }; include "/etc/rndc.key"; logging { channel my_syslog { syslog daemon; severity info; print-category yes; print-severity yes; }; channel my_file { file "debug.log"; severity dynamic; print-category yes; print-severity yes; print-time yes; }; category default { my_syslog; my_file; }; }; view "test1" IN { match-destinations { 3ffe:ffff::1; 192.168.32.2; ::ffff:192.168.32.2; }; //match-clients { // 3ffe:ffff::1; // 192.168.32.2; // ::ffff:192.168.32.2; //}; zone "." { type hint; file "/var/named/db.cache"; }; zone "0.0.127.in-addr.arpa" { type master; file "/var/named/db.127.0.0"; }; zone "localhost" {type master; file "/var/named/db.localhost"; allow-transfer { any; }; }; }; # Debug information: # dig +notcp SOA localhost @3ffe:ffff::1 ; <<>> DiG 9.2.3 <<>> +notcp SOA localhost @3ffe:ffff::1 ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51811 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;localhost. IN SOA ;; ANSWER SECTION: localhost. 604800 IN SOA ns.example.local. root.example.local. 1 604800 86400 2419200 604800 ;; AUTHORITY SECTION: localhost. 604800 IN NS ns.example.local. ;; Query time: 40 msec ;; SERVER: 3ffe:ffff::1#53(3ffe:ffff::1) ;; WHEN: Wed Jun 2 09:09:17 2004 ;; MSG SIZE rcvd: 98 Jun 02 09:10:26.813 client ::1#1031: UDP request Jun 02 09:10:26.813 client ::1#1031: using view 'test1' Jun 02 09:10:26.813 client ::1#1031: request is not signed Jun 02 09:10:26.813 client ::1#1031: recursion available: approved Jun 02 09:10:26.813 client ::1#1031: query Jun 02 09:10:26.814 client ::1#1031: ns_client_attach: ref = 1 Jun 02 09:10:26.814 client ::1#1031: query 'localhost/IN' approved Jun 02 09:10:26.814 client ::1#1031: send Jun 02 09:10:26.814 client ::1#1031: sendto Jun 02 09:10:26.814 client ::1#1031: senddone Jun 02 09:10:26.814 client ::1#1031: next Jun 02 09:10:26.814 client ::1#1031: ns_client_detach: ref = 0 Jun 02 09:10:26.814 client ::1#1031: endrequest Jun 02 09:10:26.815 client @0x9563dc0: udprecv # dig +tcp SOA localhost @3ffe:ffff::1 ; <<>> DiG 9.2.3 <<>> +tcp SOA localhost @3ffe:ffff::1 ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 61887 ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;localhost. IN SOA ;; Query time: 41 msec ;; SERVER: 3ffe:ffff::1#53(3ffe:ffff::1) ;; WHEN: Wed Jun 2 09:09:53 2004 ;; MSG SIZE rcvd: 27 Jun 02 09:10:45.444 client ::1#1026: new TCP connection Jun 02 09:10:45.444 client ::1#1026: replace Jun 02 09:10:45.444 clientmgr @0x95374d0: createclients Jun 02 09:10:45.444 clientmgr @0x95374d0: recycle Jun 02 09:10:45.445 client ::1#1026: read Jun 02 09:10:45.445 client @0x9565b80: accept Jun 02 09:10:45.446 client ::1#1026: TCP request Jun 02 09:10:45.446 client ::1#1026: no matching view in class 'IN' Jun 02 09:10:45.446 client ::1#1026: no matching view in class ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36713 ;; flags: rd ; QUESTION: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;localhost. IN SOA Jun 02 09:10:45.446 client ::1#1026: error Jun 02 09:10:45.446 client ::1#1026: send Jun 02 09:10:45.447 client ::1#1026: sendto Jun 02 09:10:45.447 client ::1#1026: senddone Jun 02 09:10:45.447 client ::1#1026: next Jun 02 09:10:45.447 client ::1#1026: endrequest Jun 02 09:10:45.447 client ::1#1026: read Jun 02 09:10:45.528 client ::1#1026: next Jun 02 09:10:45.528 client ::1#1026: request failed: end of file Jun 02 09:10:45.528 client ::1#1026: endrequest Jun 02 09:10:45.528 client ::1#1026: closetcp
After digging into the source code it looks like it's a missing feature. File: bin/named/client.c Function: client_request /* * Determine the destination address. For IPv6, we get this from the * pktinfo structure (if supported). For IPv4, we have to make do with * the address of the interface where the request was received. */ if (client->interface->addr.type.sa.sa_family == AF_INET6) { if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0) isc_netaddr_fromin6(&destaddr, &client->pktinfo.ipi6_addr); else isc_netaddr_any6(&destaddr); } else { isc_netaddr_fromsockaddr(&destaddr, &client->interface->addr); } NS_CLIENTATTR_PKTINFO is only set on IPv6-UDP queries, like seen in same function some lines above and "isc_netaddr_any6(&destaddr)" is not expected in other case by users.... if (event->ev_type == ISC_SOCKEVENT_RECVDONE) { INSIST(!TCP_CLIENT(client)); sevent = (isc_socketevent_t *)event; REQUIRE(sevent == client->recvevent); isc_buffer_init(&tbuffer, sevent->region.base, sevent->n); isc_buffer_add(&tbuffer, sevent->n); buffer = &tbuffer; result = sevent->result; if (result == ISC_R_SUCCESS) { client->peeraddr = sevent->address; client->peeraddr_valid = ISC_TRUE; } if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { client->attributes |= NS_CLIENTATTR_PKTINFO; client->pktinfo = sevent->pktinfo; } if ((sevent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0) client->attributes |= NS_CLIENTATTR_MULTICAST; client->nrecvs--; } else { INSIST(TCP_CLIENT(client)); REQUIRE(event->ev_type == DNS_EVENT_TCPMSG); REQUIRE(event->ev_sender == &client->tcpmsg); buffer = &client->tcpmsg.buffer; result = client->tcpmsg.result; INSIST(client->nreads == 1); /* * client->peeraddr was set when the connection was accepted. */ client->nreads--; } Looks either it's not so easy to get the destination address of incoming IPv6-TCP connects or someone forgot to code it.
Created attachment 100895 [details] Patch to fix not working match-destination on IPv6 TCP queries Extracted patch from 9.2.4rc4, can be clean applied to FC2's bind-9.2.3 and looks like working well.
Got information from BIND developers, this is fixed since 9.2.4rc3 (bug #1621).