I am working on an Ubuntu 14.04 server with multiple interfaces on different subnets. I am trying to write a twisted(13.2.0) application that listens for broadcasts on one interface only, ignoring the other interfaces.
I am able to receive broadcasts with this code.
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import IN, socket, struct
class BroadcastListener(DatagramProtocol):
def startProtocol(self):
self.transport.getHandle().setsockopt(socket.SOL_SOCKET,
socket.SO_BROADCAST, True)
def datagramReceived(self, datagram, address):
print "Received datagram from %s" % (address[0])
#reactor.listenUDP(65001, BroadcastListener(), interface='192.168.1.1')
reactor.listenUDP(3200, BroadcastListener())
reactor.run()
I am sending test UDP broadcasts from another machine on the 192.168.1.x subnet with socat.
echo Hi |socat - UDP-DATAGRAM:192.168.1.255:3200,broadcast
However, this will receive broadcasts on any interface on the server. I thought it would be specificying the interface in reactor.listenUDP(), as I did the commented call.
If I use the reactor.listenUDP() call that includes the interface, I no longer receive broadcast. I still receive unicasted UDP sent with socat.
echo Hi |socat - UDP-DATAGRAM:192.168.1.1:3200
I can see when specifying the interface that the socket is bound to the interface.
$ netstat -an |grep udp |grep 3200
udp 0 0 10.10.0.1:3200 0.0.0.0:*
But the broadcasts are being dropped. I confirmed with tcpdump the broadcasts are arriving to the server.
What is the correct way to set a UDP listener's interface in twisted python?