views:

12

answers:

1

I'm trying to retrofit an API to be compatible with IPv4. Basically the API at one stage creates a socket and then calls bind() to open a port for listening. The port is specified by passing a sockaddr returned by getaddrinfo(), specifying the port in the service parameter. Later, the caller has the choice of assigning a multicast group, calling an API function which sets IP_ADD_MEMBERSHIP on the socket.

The problem is that with IPv6 (i.e., family hint for getaddrinfo is AF_UNSPEC instead of AF_INET as it previously was), IP_ADD_MEMBERSHIP fails when the user asks for an IPv4 multicast group. This is because the system apparently defaults to providing an IPv6 address when no hint is provided.

The solution is obviously to know ahead of time whether the user will want to specify an IPv4 or IPv6 multicast group. However, since I'm trying not the change the API itself, this information is simply considered not known.

Do I have any other options?

I tried closing, recreating, and rebinding the socket before IP_ADD_MEMBERSHIP but my second bind() fails for some reason. (I tried specifying SO_REUSEADDR but this didn't help.)

Is there any way to simply "unbind" a socket and rebind it to a new family? Or just change the family, period?

+1  A: 

Not possible. The usual kludgey solution is to keep two sockets, one for AF_INET, one for AF_INET6.

Nikolai N Fetissov