Using dnsmasq to add SRV records for CardDAV and CalDAV

I've been working on implementing CardDAV support into DAViCal at the moment, and the first problem I encountered when I went to try and use it from iCal, was that the configuration on iCal didn't seem to want to let me enter a URL to my addressbook.

I've been working on implementing CardDAV support into DAViCal at the moment, and the first problem I encountered when I went to try and use it from iCal, was that the configuration on iCal didn't seem to want to let me enter a URL to my addressbook.

After I hauled out Wireshark and watched what was happening on the server it was clear that it was doing an SRV request to try and find the CardDAV server for the domain I had entered in. Unfortunately the DNS management front-end that I normally use doesn't support SRV records, so I was all ready to switch my whole DNS infrastructure around (one of those 'round tuit' tasks that's been on my todo list for somewhat more than a year) until I wondered if the magic that is dnsmasq would be able to help me out.

It turns out that it can, and so after a little searching I'd managed to track down the magic syntax to do this:

srv-host=_caldav._tcp.home.mcmillan.net.nz.,davical.home.mcmillan.net.nz.,8008
srv-host=_carddav._tcp.home.mcmillan.net.nz.,davical.home.mcmillan.net.nz.,8008

Of course this is a special-case server for testing at home, and I run it on the funny port because it makes for less pollution when I sniff the traffic coming in.

In the real world you'd want to add SRV records for caldavs and carddavs, to get SSL for these services, something like:

srv-host=_caldavs._tcp.home.mcmillan.net.nz.,davical.home.mcmillan.net.nz.,443
srv-host=_carddavs._tcp.home.mcmillan.net.nz.,davical.home.mcmillan.net.nz.,443

Once I'd done that, and put in a few more hours of debugging, DAViCal was working with iCal's CardDAV, at least for viewing / editing / deleting contacts - there's still some work to do yet on searching. I've now also got it working with Evolution's 'WebDAV contacts' plugin as well, after a tip from Milan Crha on the Evolution IRC channel.

Heather gets home soon with the Apple phone I gave her when I upgraded to Android, so I'll hopefully be able to test against their new OS release and then get a new DAViCal release out next week. Maybe. Hopefully :-)

This sounds nice. But, is it

This sounds nice.
But, is it possible to use the carddav server with apples addressbook now?
I think this could bring autocompletion for invite to iCal.

Yes, it's working in Apple's Addressbook

Yes, the current head is working (for me) with Apple's Addressbook. At least as far as basic storing, editing and deleting of addresses in a DAViCal-hosted addressbook.

I need to confirm whether/how lookups happen and go through a bunch more exercises on the Macbook before I can release it publicly though.

Cheers,
Andrew.

Well, darn

Darn .. My DNS service doesn't seem to support SRV records either.

I don't have a Mac Address Book to play with right now, because I'm still running Leopard at home, and it doesn't do CardDav.

But I do have an iPhone, running IOS 4. So I decided to try setting up a CardDav account, just to see what it would do.

In the setup screen, it asks for a "server", without giving a clue whether that should be a URL or something else. Experimenting a little, it seems that it wants just a fully-qualified domain name. Anything else gets chopped off.

So I gave it the address of my caldav server, just to see what it would do. Naturally, it didn't work, but here's what I got in my server log:

75.207.39.115 - - [23/Jun/2010:23:45:26 -0400] "OPTIONS /.well-known/carddav HTTP/1.1" 200 - "-" "DataAccess/1.0 (8A293)"
75.207.39.115 - - [23/Jun/2010:23:45:27 -0400] "OPTIONS / HTTP/1.1" 200 - "-" "DataAccess/1.0 (8A293)"

I don't have the ability to trace to see if it did a DNS SRV request first, but if it did, that would have failed. So either the iPhone doesn't do SRV requests, or if they fail, it just tries to get information from the server address given.

This seems to imply that providing Carddav access to an iPhone would require that the carddav server runs at the root level of the web server at the specified address. This should be OK for servers with Virtual Host capability. It probably also means that the server needs to respond to the OPTIONS request with something the client understands, and that's starting to get over my head.

Handling /.well-known/carddav and /.well-known/caldav URLs

The '/.well-known/carddav' approach is defined in "Use of SRV records for locating CalDAV and CardDAV services" and while I hadn't found iCal4 hitting that URL I had expected it to.

Actually I was really surprised at how crude the iCal4 CardDAV client is - it seems to send somewhat more than twice the numbers of requests that it needs, first trying to do whatever it is without authentication, and then (reluctantly, it would seem) providing the credentials.

You should be able to do a simple redirect on that URL, however, to point it at /caldav.php/.

The next release handles /.well-known/ as well, and will do the redirect internally, so the standard rewrite rules will handle the new situation transparently in many circumstances. Obviously those people running in a subdirectory will still need to add the redirects for those URLs, but in fact the whole point of those URLs is so that it doesn't need to run in the root - you just need to be able to redirect from there.

Cheers,
Andrew.

ical and carddav

Interesting. I'm back at work with a Snow Leopard system to play with. I tried setting up a CardDav account in ical. The setup looked very similar to what I saw on the iphone: user name, password, and server address.

So I plugged in the info for my davical server. I'm running Little Snitch on my Mac, which reports and prompts for approval for unknown outbound network requests. It reported an outbound attempt for access to port 8843, and then one to port 8800, and then it told me it "couldn't discover the account settings for the CardDAV server". Not surprising, since I don't have a CardDav server, and don't have anything at all listening to those ports.

Again, I don't know whether it tried to do a DNS SRV lookup. If it did try, it would have failed. It's possible that if it doesn't find an SRV record to give it host and port info, it defaults to trying port 8843 for SSL, and then 8800 for non-SSL.

If this is the way it works, then maybe I can get by without SRV records. I can make the server listen to the correct ports if that's all it takes.

ical and carddav - more info

More info to add to my previous post. I thought it was interesting (although not totally surprising) that iPhone Address Book and Snow Leopard Address Book behaved differently in their choice of default ports. So I tried adding port number to the server address. When I did that, I was able to make them hit port 80 on my server. There's still a difference in behavior though. The iPhone still tried the /.well-known/carddav URI, but the Mac Address book didn't. It just issued a PROPFIND request for the root at the specified address:

128.163.134.241 - - [25/Jun/2010:10:08:59 -0400] "PROPFIND / HTTP/1.1" 405 226 "-" "Address%20Book/870 CFNetwork/454.9.7 Darwin/10.4.0 (i386) (iMac7%2C1)"

iCal4 does not do /.well-known/

Snow Leopard addressbook does not seem to do /.well-known/carddav lookups, and iPhone does not appear to do SRV record lookups. Sigh.

Oh well: I guess in the next version of each they'll both do the missing bits.

What I found annoying though, was that in spite of not doing /.well-known/carddav lookups I was not able to configure the Snow Leopard addressbook application to use my CardDAV server by just supplying the host name. It really should fall back to using the host name directly if it can't find any related SRV records.

Cheers,
Andrew.

Are you sure about the

Are you sure about the caldavs part? It is not supposed to be like that. The correct syntax is _caldav._tls.[domain]. It is already used that way in both SIP and Jabber/XMPP. Is Apple inventing their own syntax here?

Yes, it is _carddavs._tcp rather than _carddav._tls

Don't take my word for it! Check the spec :-)

http://tools.ietf.org/html/draft-ietf-vcarddav-carddav-10#section-11.

Cheers,
Andrew.

Interestingly...

I've been playing with this the last couple days, and what I seem to be hitting is:

Address Book and iCal in 10.6 use SRV records nicely. If I tell iCal that my server is www.example.com, and I have an SRV record that says "_caldavs._tcp.www.example.com. 86400 IN SRV 0 0 8443 caldav.example.com.", iCal magically figures out that my actual caldav server is caldav.example.com.

The PROBLEM is that iOS (iPhone 4, 4.1, and seemingly 4.2) don't pay attention to SRV records, at all. They look for /.well-known/caldav. Which, is fine I suppose, though annoying since Apple says to use SRV records. The issue is, I can't find ANY documentation on what that file should be, or do.

I've tried just about every type of redirect I can figure out that redirects www.example.com/.well-known/caldav to caldav.example.com, but no matter what, iOS keeps trying to login to caldav on www.example.com. So if it gets a 301, it doesn't pay attention, it just keeps trying.

The RFC for /.well-known/ just establishes a registry for .well-known. For all we know, iOS is looking for actual data inside that caldav or carddav file in /.well-known/ rather than just a 301 to the proper location.

Any thoughts? I'd really like to get this going so as to make things easier for my iOS users... but there seems to be NO documentation from Apple or anyone else on this.... and I get the impression the person that wrote the https://datatracker.ietf.org/doc/draft-daboo-srv-caldav/ draft seemed to think iOS supported SRV records. But I could be wrong. =/ Maybe I just need to sign up to be an iOS dev.

DAViCal knows what /.well-known/carddav should go

So you can hand it off to DAViCal. If you need to map /.well-known/blah to something else you can manually map just /.well-known/carddav and /.well-known/caldav to /caldav.php and it should just work.

If you want DAViCal to handle all URLs that don't really exist on the file system you can use some funky mod_rewrite logic like:

#Activate RewriteEngine
RewriteEngine On
# Filter all files that do not exist
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# and redirect them to our caldav.php
RewriteRule ^(.*)$ /caldav.php/$1 [NC,L]

As outlined in the DAViCal wiki, here: CardDAV/Configuration/Well-known URLs.

Note that the CardDAV docs in the wiki are currently under development, and any help is appreciated :-)

Cheers,
Andrew.

[D] [Digg] [FB] [R] [SU] [Tweet]