1

SSDP M-search request for discovery works great for multicast address 239.255.255.250. However, I have a requirement to send this request to a specific IP. It does not work. As per the UPnP architecture document unicast discover message is supported, with a small difference from the multicast message

The multi-cast message is M-SEARCH * HTTP/1.1 HOST:239.255.255.250:1900 MAN:ssdp:discover ST:ssdp:all MX:1

Unicast message is similar - except that the multicast IP is changed to specific IP and MX:1 is removed (as per the specification - did not find any code sample for unicast discover m-search)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)
msg = 'M-SEARCH * HTTP/1.1\r\nHOST:239.255.255.250:1900\r\nMAN:\"ssdp:discover\"\r\nST:ssdp:all\r\nMX:1\r\n\r\n'
s.sendto(msg.encode('utf-8'), ('239.255.255.250', 1900))
resp = s.recv(1024)
print (resp)

This works great. But the following doesn't - the recv() call times out

sock_1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
msg = 'M-SEARCH * HTTP/1.1\r\nHOST:<specific ip>:1900\r\nMAN:\"ssdp:discover\"\r\nST:ssdp:all\r\n\r\n'
sock_1.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)
sock_1.settimeout(30)
sock_1.sendto(msg.encode('utf-8'), ('<specific ip>', 1900))
resp = sock_1.recv(1024)

I have tried a few more variations of 'setsockopt' which did not work. Please share if there are any clues for possible reasons - could it be from the device side that it responds to the multicast on 1900 but not to the unicast message?

Thanks in advance!

samiksc
  • 167
  • 10

2 Answers2

0
msg = 'M-SEARCH * HTTP/1.1\r\nHOST:<specific ip>:1900\r\nMAN:\"ssdp:discover\"\r\nST:ssdp:all\r\n'

You're missing a final \r\n in the end (it's for the empty line signaling end of headers: without it the receiver will just keep waiting for more).

Jussi Kukkonen
  • 13,857
  • 1
  • 37
  • 54
0

The only difference with a unicast m-search is the HOST, like you've got.

Are you binding the socket? It should be bound to port 0. Here's an example of setting up a socket for ssdp: https://github.com/lbryio/aioupnp/blob/master/aioupnp/protocols/multicast.py#L64

In addition to the final \r\n pointed out by Jussi, you may find you need to try different permutations of the M-SEARCH format, some gateways are very finicky. For some the value for MAN must be in quotes, for others it must not. Additional quirks are the order of MAN, MX, ST and the capitalization of HOST/Host and MAN/Man . You may also need to try a variety of search targets.

Jack Robison
  • 134
  • 3
  • Is socket binding required for creating 'client' socket? I believe bind is for server side.The multicast discovery is working fine without bind. – samiksc Sep 03 '19 at 05:14
  • Tried a few combinations of removing quotes, and using small case MAN/ST/HOST. It didn't help. Can we know specifics by any way for a particular device? – samiksc Sep 03 '19 at 05:44