Quantcast
Channel: Jobs
Viewing all articles
Browse latest Browse all 18427

Problem binding UDP (server) socket to an interface

$
0
0
I am writing a UDP server application that needs to know which interface received a request, so I can know what IP address to deliver in the response. To accomplish that, I am creating a separate UDP socket for each interface, and binding each socket to a specific interface address. Here is a piece of code so you can see what I am doing to initialize it: PXEResponder::PXEResponder(QObject *parent)     : QObject(parent) {     bool ok;       // Get network interface list     addresses = QNetworkInterface::allAddresses();       signalMapper = new QSignalMapper(this);     listeners.reserve(interfaces.size());       for (int i = 0; i < addresses.size(); ++i)     {         // Only support IPv4         if (addresses[i].protocol() != QUdpSocket::IPv4Protocol)             continue;           qDebug() << addresses[i];           // Create a UDP socket and bind it to port 67         QUdpSocket *listener = new QUdpSocket(this);         if (!listener->bind(addresses[i], 67, QUdpSocket::DefaultForPlatform))         //if (!listener->bind(67))             qDebug() << "Failed to bind DHCP listener";           // Connect the readyRead signal to our slot         ok = connect(listener, SIGNAL(readyRead()), signalMapper, SLOT(map()));         signalMapper->setMapping(listener, i);           listenerAddress.insert(listener, addresses[i]);         listeners.push_back(listener);     }       ok = connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(on_packet(int))); } Everything completes without error, but I don’t get any readyRead signals. NOTE: My program is running as root, so it is allowed to bind port 67 There is no DHCP server running on my machine I am using the signal mapper so I can identify which QUdpSocket causes the event. That part works. The “bind” call that doesn’t work (the one that specifies an address) returns true. Removing the “QUdpSocket::DefaultForPlatform” parameter doesn’t help. The qDebug() output (the interface address) looks correct. If I comment-out the bind call that I’m trying to use, and uncomment the one that doesn’t specify an interface address, everything works. Here’s the weird part: when I bind to specific interfaces, I see the socket in the “netstat -a” output. Is there a reason I am not receiving broadcasts when bound to a specific interface? I found a partial answer: Linux won’t receive broadcast packets when the socket is bound because it will only receive packets sent (directly) to the bound address. The solution is to use SO_BINDTODEVICE socket option and use INADDR_ANY as the bind address. Is there a way to bind to a network interface in Qt (without binding to the address of the interface)?

Viewing all articles
Browse latest Browse all 18427

Trending Articles