Divert Name lookups

This file was used to override calls made by an application to look up names. So if not wanting to set up address records on a SRV enabled name, compiled as gcc -shared -Wl,-soname,libdivert.so -o libdivert.so libdivert.c -ldl -fPIC

This allows the application with known problems to connect, and does not affect other applications, so SRV problems with them remain noticable. It works by intercepting calls to functions like getaddrinfo

NAT64 without DNS64

Now with a 2016 addition, do very experimental nat64 address rewriting for use with a nat64 gateway without needing to corrupt DNSSEC signed results at our resolver. Thus accesses to an IPv4 address is forced via an 64:ff9b::/96 IPv6 address range.

This is similar to Android CLAT. That only needs ipv4only.arpa configered to allow systems to discover that 64:ff9b:: is ready and waiting.

This is being used very successfully with most applications tried. A few do not work with getaddrinfo interception, this is mainly the case where the app code did not consider IPv6.

This situaton is handled in socket creation and connect time.

env LD_PRELOAD=libdivert.so LD_LIBRARY_PATH=. iceweasel

Try that with chromium and we get some error: ERROR: ld.so: object 'libdivert.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.

In this case qualify the path and was working.

env LD_PRELOAD=/path/to/libdivert.so /usr/lib/chromium/chromium

Lets also monitor for library calls to see about other functions worth overriding such as to handle IPv4 literals via NAT64 as highlighted by test ipv6

2>&1 ltrace -f -e gethost*+getaddr* -p `pidof chromium | sed 's/ / -p /g'`

Some sites do not work over nat64?

If jumbograms are in use locally, and yes I would do it, it may be necessary to make an exception for nat64, if they discard fragments or suchlike.

for /etc/init.d/tayga as /etc/default/tayga had no place to put an mtu adjustment:

ip link set "$TUN_DEVICE" up mtu 65535

IPv6 carried frames are bigger:

/sbin/ip -6 route replace 64:ff9b::/96 dev nat64 mtu 1520

To use…

Set environment variables to load it and choose the server to connect.

This would make ekiga look up sip.example.net if it tries to connect directly to example.net

env example.net=sip.example.net FLASH_ALSA_DEVICE=plug:SLAVE=jack LD_PRELOAD=/somewhere/libdivert.so ekiga

Therefore if your SIP server is on sip.example.net and there is no desire to add address records to example.net it will still connect.

Regarding FLASH_ALSA_DEVICE

It is possible to set up the ~/.asoundrc file to pull the default sound device from an environment variable, so that the audio device for programs that cannot be configured to use anything other than the default device and the hardware drivers can be set, such as env FLASH_ALSA_DEVICE=plug:SLAVE=jack ekiga

FLASH_ALSA_DEVICE is chosen as Adobe Flash reads it to find the ALSA device to play to.

The variable is read when the program uses ALSA, allowing different programs to use different devices.

pcm.!default { @func getenv vars [ FLASH_ALSA_DEVICE ] default "cards.pcm.default" }

pcm.jds { @func getenv vars [ JACK_DEFAULT_SERVER ] default "defaults.pcm.card" }

pcm.jack {
        type jack
        playback_ports {
               0 alsa_pcm:playback_1
               1 alsa_pcm:playback_2
        }
        capture_ports {
               0 alsa_pcm:capture_1
               1 alsa_pcm:capture_2
        }
}

Socket Activation

systemd provides the ability to dynamically run services with a precreated collection of file descriptors, and it it really good as a server can just run up services when they are actually being used, together with crash resistent resilience.

Unfortunately support in services is sparse, and of those that do often support only working on a connection whatever@.service rather than a whole listening socket.

I consider the ability of an LD_PRELOAD to do something.

Without some action, TCP and UDP services fail as the port is already bound, and local sockets end up with a second binding, and don't take the first connection.

running strace and ltrace on a service process at the console shows they make a sequence of socket(), bind() and other syscalls whereas socket issues a file-descriptor and the bind gets it ready to accept connections.

A tradeoff of implementaton

The implementation thought unstable would be to just intercept bind() and look for the qualifying socket by reading the bind cal parameters, then dup2() in the "real" descriptor, but the kernel would of course notice that and may have different behaviour.

Instead, as the calls to socket() are generally predictable whilst a service is starting up, count them and return the real file descriptor on the one that would be used to call bind(), then discard the following bind call. Doing this is thought to be safer though requires inspecting the service to work out how many socket() calls pass by before the "real" one(s) to replace its file descriptor, once that is done the software can drop out.

By replacing the actual descriptor, and no extra state changing system calls, it would look to the kernel much more like the service is a native systemd socket service. It does have the side effect that library calls need to be counted to get the correct place to throw in the real descriptors. 😸

Initially, statically look for file-descriptor by number, later iterate up until SYSTEMD_MAX_FDS looking for preopened fd matching a pattern, such as a path for a local socket or IP address and port.

SRV is implemented here.

This server does provide SRV records for most of the addresses intended to be websites.

Try dig _http._tcp.www.wensley.org.uk SRV.

I avoid an IP address at the root of the domain, as this activates fallback mechanisms in applications and therefore prevents fixing underlying problems. So, it is needed to pick a subdomain for the site, so may as well use the www.