Author: axeld Date: 2010-08-27 13:05:13 +0200 (Fri, 27 Aug 2010) New Revision: 38397 Changeset: http://dev.haiku-os.org/changeset/38397 Ticket: http://dev.haiku-os.org/ticket/6454 Modified: haiku/trunk/src/add-ons/kernel/network/protocols/udp/udp.cpp Log: * UDP now respects the net_socket::bound_to_device field when propagating data to endpoints. This should help with the final issues of bug #6454. Modified: haiku/trunk/src/add-ons/kernel/network/protocols/udp/udp.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/protocols/udp/udp.cpp 2010-08-27 10:57:03 UTC (rev 38396) +++ haiku/trunk/src/add-ons/kernel/network/protocols/udp/udp.cpp 2010-08-27 11:05:13 UTC (rev 38397) @@ -187,7 +187,7 @@ status_t _FinishBind(UdpEndpoint *endpoint, const sockaddr *address); UdpEndpoint *_FindActiveEndpoint(const sockaddr *ourAddress, - const sockaddr *peerAddress); + const sockaddr *peerAddress, uint32 index = 0); status_t _DemuxBroadcast(net_buffer *buffer); status_t _DemuxUnicast(net_buffer *buffer); @@ -493,7 +493,7 @@ UdpEndpoint * UdpDomainSupport::_FindActiveEndpoint(const sockaddr *ourAddress, - const sockaddr *peerAddress) + const sockaddr *peerAddress, uint32 index) { ASSERT_LOCKED_MUTEX(&fLock); @@ -501,7 +501,20 @@ AddressString(fDomain, ourAddress, true).Data(), AddressString(fDomain, peerAddress, true).Data()); - return fActiveEndpoints.Lookup(std::make_pair(ourAddress, peerAddress)); + UdpEndpoint* endpoint = fActiveEndpoints.Lookup( + std::make_pair(ourAddress, peerAddress)); + + // Make sure the bound_to_device constraint is fulfilled + while (endpoint != NULL && index != 0 + && endpoint->socket->bound_to_device != index) { + endpoint = endpoint->HashTableLink(); + if (endpoint != NULL + && (!endpoint->LocalAddress().EqualTo(ourAddress, true) + || !endpoint->PeerAddress().EqualTo(peerAddress, true))) + return NULL; + } + + return endpoint; } @@ -524,6 +537,10 @@ TRACE_DOMAIN(" _DemuxBroadcast(): checking endpoint %s...", AddressString(fDomain, *endpoint->LocalAddress(), true).Data()); + if (endpoint->socket->bound_to_device != 0 + && buffer->index != endpoint->socket->bound_to_device) + continue; + if (endpoint->LocalAddress().Port() != incomingPort) { // ports don't match, so we do not dispatch to this endpoint... continue; @@ -559,19 +576,20 @@ const sockaddr* peerAddress = buffer->source; // look for full (most special) match: - UdpEndpoint* endpoint = _FindActiveEndpoint(localAddress, peerAddress); + UdpEndpoint* endpoint = _FindActiveEndpoint(localAddress, peerAddress, + buffer->index); if (endpoint == NULL) { // look for endpoint matching local address & port: - endpoint = _FindActiveEndpoint(localAddress, NULL); + endpoint = _FindActiveEndpoint(localAddress, NULL, buffer->index); if (endpoint == NULL) { // look for endpoint matching peer address & port and local port: SocketAddressStorage local(AddressModule()); local.SetToEmpty(); local.SetPort(AddressModule()->get_port(localAddress)); - endpoint = _FindActiveEndpoint(*local, peerAddress); + endpoint = _FindActiveEndpoint(*local, peerAddress, buffer->index); if (endpoint == NULL) { // last chance: look for endpoint matching local port only: - endpoint = _FindActiveEndpoint(*local, NULL); + endpoint = _FindActiveEndpoint(*local, NULL, buffer->index); } } }