Frustrated with an endless succession of failed/disrupted Dynamic DNS services, I wrote this simple daemon in Python2.
It accepts a simple datagram update from its clients (but SHA signed to reduce nonsense), and records their visible IP address. It then serves as a standard DNS server, answering with addresses as updated from its clients.
Typically, you would have this daemon serve a sub-domain of your overall domain, such as dyn.mydomain.com. Then each dynamic client gets a name like joseph.dyn.mydomain.com.