SSDP and interface IP address
Asked Answered
H

1

3

I'm writing a UPnP AV/DLNA DMS which needs to send and receive SSDP messages. In response to some M-SEARCH packets I need to send a reply with the URL of a resource (in this case a HTTP server), which I've chosen to bind to INADDR_ANY (0.0.0.0). Of course this address is meaningless to the sender of the M-SEARCH packet: The address of the interface on which the M-SEARCH was received is most appropriate.

How can I determine the appropriate address to send in the reply packet?

Some ideas I've considered are:

  1. Binding a different receiver to each socket. When a receiver gets an M-SEARCH packet, the reply address can use the socket's local address in the reply. However this requires knowing and iterating over all the interfaces, and adding and removing receivers as interface availability changes.
  2. Put a single receiver on INADDR_ANY, and iterate interface netmasks to determine the possible source. However more than one interface might share the same subnet.
  3. Extract the packets IP target address upon receiving it. This would be IP specific, and may be lost somewhere in the network abstraction.
Heartbreak answered 4/3, 2011 at 12:8 Comment(0)
M
2

getsockname(2) followed by getnameinfo(3) reports the IP address that your TCP/IP stack has assigned to the socket. (Obviously, this won't match what the client could use if server and client are on opposite sides of a NAT system; in that case, perhaps there is clever UPnP trickery to discover the IP address that the client could use to contact the server.)

I assume your server looks something like this:

lfd = socket();
ret = bind(lfd,...);
connection = listen(lfd, 10);
/* add connection to your select queue or poll queue */

You could append code similar to this:

struct sockaddr_storage me;
socklen_t *len = sizeof(me);
char name[40];
ret = getsockname(connection, &me, &len);
ret = getnameinfo(&me, &len, name, sizeof(name), NULL, 0, NI_NUMERICHOST);

getnameinfo(3) inspects the struct sockaddr_storage me for your IP address. Because these are generic interfaces, it'll work for IPv4 or IPv6 addresses.

Magma answered 4/3, 2011 at 12:45 Comment(3)
SSDP is over UDP... not sure what you've said is applicable.Heartbreak
@Matt Joiner: Ah, I saw plenty of "HTTP" mentions on the Wikipedia page and assumed it was TCP. You can connect UDP sockets, and then use getsockname(2) on the connected socket. I'm less sure about unconnected sockets, but connecting sockets isn't horrible.Magma
this seems to work. i should rephrase the question to focus on UDP.Heartbreak

© 2022 - 2024 — McMap. All rights reserved.