DLZ / DDNS / Transactions

Marty Lee <[email protected]> Tue, 1 Apr 2014 17:38:34 +0100
Newsgroups gmane.network.dns.bind9.dlz
Message-ID <[email protected]>
--===============5476167093358405424==
Content-Type: multipart/signed;
	boundary="Apple-Mail=_BBCBA735-323A-4808-96B5-0F587006C1DA";
	protocol="application/pgp-signature"; micalg=pgp-sha1


--Apple-Mail=_BBCBA735-323A-4808-96B5-0F587006C1DA
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=windows-1252

Apologies if you are also subscribed to the main bind discussion list
and have seen this over there. Evan just pointed out the DLZ mailing
list, so I=92m posting something here, in case someone more astute than
me finds this archive first.

Problem:

ISC DHCP doing DDNS updates to a custom MySQL DLZ module; some data made
it into the database, but Bind seemed to delete A records almost as =
quickly
as it added them, leaving =92TXT=92 records (interim DDNS style) for the
leases, but no A records.

Diagnosis:

The anatomy of a DDNS update through a DLZ module is:

- DHCP server sends DDNS update (pre-req followed by update details)
- Bind calls the DLZ =92newversion=92 function to start a new =
=92transaction=92
- Pre-req=92s are checked, and if they fail, DLZ =91closeversion=92 is =
called
  without the commit flag set; the DLZ cancels the transaction.
- Bind calls the DLZ =91addrdataset=92 or =92subrdataset=92 functions to =
change
  the DNS data
- Bind calls =91closeversion=92 with the =91commit=92 flag set to apply =
the changes.

All sounds good=85 however there are also some other bits going on =
behind the
scenes=85

- during the =91addrdataset=92 calls, Bind queries the DLZ to see if the =
data is
  already present in the data store; if it is, it silently skips the =
=91add=92.


In my module, I used MySQL transaction functionality; storing some
private data in the =91versionp=92 parameter created during the =
=91newversion'
call. =91versionp=92 is passed to =91addrdataset=92 and =91subrdataset=92,=
 so all
adds and deletes can use the same MySQL connection and live within the
transaction.

=91closeversion=92 then either =91COMMIT=92s or =91ROLLBACK=92s the =
transaction;
again, the =91versionp=92 structure is passed to =91closeversion', so =
this
all seems to be logical to me.

Issues:

In summary, the =91dlz_lookup=92 function isn=92t passed the =91versionp=92=
 data,
so in my case, it just queries the normal database data outside of the
transaction.

This means that the =91anatomy=92 changes subtly:
- DHCP server sends DDNS update (pre-req followed by update details)
- Bind calls the DLZ =92newversion=92 function to start a new =
=92transaction=92
- Pre-req=92s are checked, and if they fail, DLZ =91closeversion=92 is =
called
  without the commit flag set; the DLZ cancels the transaction.
- Bind calls the DLZ =91addrdataset=92 or =92subrdataset=92 functions to =
change
  the DNS data
** Bind removes the =91A=92 record in the transaction through =
=91subrdataset=92
** Bind tries to add the new =91A=92 record, and quietly checks to see =
if
   the record already exists using dlz_lookup outside of the uncommitted
   transaction where the =91A=92 record hasn=92t been deleted!
   The Bind =91add=92 code, then silently skips the actual =91add=92.
- Bind calls =91closeversion=92 with the =91commit=92 flag set to apply =
the changes.
** The transaction now commits, and the =91A=92 record is deleted.
** As the =91add=92 was skipped=85=85  ooops

=97

What this looks like in reality, is the =91A=92 record being added first
time through. When the client renews it=92s lease, the DDNS update =
removes
the =91A=92 record, only leaving the =91TXT=92 record behind. Third time =
through,
the =91A=92 record is added again; fourth time through, it=92s =
deleted...
Repeat until you bash your head against a wall as sometimes you can
resolve your IP address, sometimes you can=92t=85=20

Naturally, you initially blame your own DLZ code=85

=97

My approach to fixing it:

I=92ve submitted patches to ISC to allow the =91versionp=92 structure to
be visible through the =91clientinfo=92, which is passed to dlz_lookup.

This means that DLZ authors can take the option of picking up that
variable to let you query against the right version of the database.

I=92m guessing that anyone else that=92s played with DLZ and DDNS has
either just applied changes to the DB directly and then tracked
those changes should they need to be rolled back; or maybe nobody
has really played with DLZ, DDNS and implemented the transactions
fully before=85

Anyway, until I hear back from ISC, if anyone wants the patches,
feel free to get in touch.

Cheers

marty

  =20
-----
Marty Lee                         e: [email protected]
Technical Director                v: +44 845 869 2661
Maui Systems Ltd                  f: +44 871 433 8922
Scotland, UK                      w: http://www.maui-systems.co.uk


--Apple-Mail=_BBCBA735-323A-4808-96B5-0F587006C1DA
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename=signature.asc
Content-Type: application/pgp-signature;
	name=signature.asc
Content-Description: Message signed with OpenPGP using GPGMail

-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org

iEYEARECAAYFAlM664oACgkQ7kOn6bnA9094mwCgjJ6ifcUKofU2r4Iq/Je0XiQa
7+0AnR7dK6AUtuhaUSKSOOnWsk5PEkYx
=d0eb
-----END PGP SIGNATURE-----

--Apple-Mail=_BBCBA735-323A-4808-96B5-0F587006C1DA--


--===============5476167093358405424==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

------------------------------------------------------------------------------

--===============5476167093358405424==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Bind-dlz-testers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bind-dlz-testers

--===============5476167093358405424==--