[haiku-commits] r38365 - in haiku/trunk/src/add-ons/kernel/network/protocols: ipv4 udp

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 26 Aug 2010 11:23:50 +0200 (CEST)

Author: axeld
Date: 2010-08-26 11:23:49 +0200 (Thu, 26 Aug 2010)
New Revision: 38365
Changeset: http://dev.haiku-os.org/changeset/38365
Ticket: http://dev.haiku-os.org/ticket/6454

Modified:
   haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp
   haiku/trunk/src/add-ons/kernel/network/protocols/udp/udp.cpp
Log:
* Now we should also support link layer and INADDR_BROADCAST broadcasts again
  correctly.
* This should finally fix ticket #6454, but I keep it open until it's confirmed.


Modified: haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp      
2010-08-26 09:16:18 UTC (rev 38364)
+++ haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp      
2010-08-26 09:23:49 UTC (rev 38365)
@@ -1581,6 +1581,7 @@
        // lower layers notion of broadcast or multicast have no relevance to us
        // other than deciding whether to send an ICMP error
        bool wasMulticast = (buffer->flags & (MSG_BCAST | MSG_MCAST)) != 0;
+       bool notForUs = false;
        buffer->flags &= ~(MSG_BCAST | MSG_MCAST);
 
        sockaddr_in destination;
@@ -1590,29 +1591,33 @@
                buffer->flags |= MSG_BCAST;
 
                // Find first interface with a matching family
-               // TODO: support for ethernet broadcasts!
-               // TODO: we might need to send it to all interfaces if it's an 
ethernet
-               // broadcast as well!
-               sDatalinkModule->is_local_link_address(sDomain, true,
-                       buffer->destination, &buffer->interface_address);
+               if (!sDatalinkModule->is_local_link_address(sDomain, true,
+                               buffer->destination, 
&buffer->interface_address))
+                       notForUs = wasMulticast;
        } else if (IN_MULTICAST(ntohl(header.destination))) {
                buffer->flags |= MSG_MCAST;
-               // TODO: must set buffer->interface_address!
        } else {
                uint32 matchedAddressType = 0;
 
                // test if the packet is really for us
                if (!sDatalinkModule->is_local_address(sDomain, 
(sockaddr*)&destination,
-                               &buffer->interface_address, 
&matchedAddressType)) {
-                       sDatalinkModule->is_local_link_address(sDomain, true,
-                               buffer->destination, 
&buffer->interface_address);
+                               &buffer->interface_address, &matchedAddressType)
+                       && !sDatalinkModule->is_local_link_address(sDomain, 
true,
+                               buffer->destination, 
&buffer->interface_address)) {
+                       notForUs = true;
                } else {
                        // copy over special address types (MSG_BCAST or 
MSG_MCAST):
                        buffer->flags |= matchedAddressType;
                }
        }
 
-       if (buffer->interface_address == NULL) {
+       // set net_buffer's source/destination address
+       fill_sockaddr_in((struct sockaddr_in*)buffer->source, header.source);
+       memcpy(buffer->destination, &destination, sizeof(sockaddr_in));
+
+       buffer->protocol = header.protocol;
+
+       if (notForUs) {
                TRACE("  ipv4_receive_data(): packet was not for us %x -> %x",
                        ntohl(header.source), ntohl(header.destination));
 
@@ -1625,12 +1630,6 @@
                return B_ERROR;
        }
 
-       // set net_buffer's source/destination address
-       fill_sockaddr_in((struct sockaddr_in*)buffer->source, header.source);
-       memcpy(buffer->destination, &destination, sizeof(sockaddr_in));
-
-       buffer->protocol = header.protocol;
-
        // remove any trailing/padding data
        status_t status = gBufferModule->trim(buffer, packetLength);
        if (status != B_OK)

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-26 09:16:18 UTC (rev 38364)
+++ haiku/trunk/src/add-ons/kernel/network/protocols/udp/udp.cpp        
2010-08-26 09:23:49 UTC (rev 38365)
@@ -234,8 +234,10 @@
        static  int                                     DumpEndpoints(int argc, 
char *argv[]);
 
 private:
-                       UdpDomainSupport*       _GetDomain(net_domain *domain, 
bool create);
-                       UdpDomainSupport*       _GetDomain(net_buffer* buffer);
+       inline  net_domain*                     _GetDomain(net_buffer* buffer);
+                       UdpDomainSupport*       _GetDomainSupport(net_domain* 
domain,
+                                                                       bool 
create);
+                       UdpDomainSupport*       _GetDomainSupport(net_buffer* 
buffer);
 
                        mutex                           fLock;
                        status_t                        fStatus;
@@ -504,23 +506,21 @@
 
 
 status_t
-UdpDomainSupport::_DemuxBroadcast(net_buffer *buffer)
+UdpDomainSupport::_DemuxBroadcast(net_buffer* buffer)
 {
-       sockaddr *peerAddr = buffer->source;
-       sockaddr *broadcastAddr = buffer->destination;
-       sockaddr *mask = NULL;
+       sockaddr* peerAddr = buffer->source;
+       sockaddr* broadcastAddr = buffer->destination;
+       uint16 incomingPort = AddressModule()->get_port(broadcastAddr);
+
+       sockaddr* mask = NULL;
        if (buffer->interface_address != NULL)
-               mask = (sockaddr *)buffer->interface_address->mask;
+               mask = (sockaddr*)buffer->interface_address->mask;
 
-       TRACE_DOMAIN("_DemuxBroadcast(%p)", buffer);
+       TRACE_DOMAIN("_DemuxBroadcast(%p): mask %p\n", buffer, mask);
 
-       uint16 incomingPort = AddressModule()->get_port(broadcastAddr);
+       EndpointTable::Iterator iterator = fActiveEndpoints.GetIterator();
 
-       EndpointTable::Iterator it = fActiveEndpoints.GetIterator();
-
-       while (it.HasNext()) {
-               UdpEndpoint *endpoint = it.Next();
-
+       while (UdpEndpoint* endpoint = iterator.Next()) {
                TRACE_DOMAIN("  _DemuxBroadcast(): checking endpoint %s...",
                        AddressString(fDomain, *endpoint->LocalAddress(), 
true).Data());
 
@@ -540,7 +540,7 @@
                }
 
                if (endpoint->LocalAddress().MatchMasked(broadcastAddr, mask)
-                       || endpoint->LocalAddress().IsEmpty(false)) {
+                       || mask == NULL || 
endpoint->LocalAddress().IsEmpty(false)) {
                        // address matches, dispatch to this endpoint:
                        endpoint->StoreData(buffer);
                }
@@ -675,7 +675,7 @@
 {
        TRACE_EPM("ReceiveData(%p [%" B_PRIu32 " bytes])", buffer, 
buffer->size);
 
-       UdpDomainSupport* domainSupport = _GetDomain(buffer);
+       UdpDomainSupport* domainSupport = _GetDomainSupport(buffer);
        if (domainSupport == NULL) {
                // we don't instantiate domain supports in the receiving path, 
as
                // we are only interested in delivering data to existing 
sockets.
@@ -710,7 +710,7 @@
        if (buffer->size < 4)
                return B_BAD_VALUE;
 
-       UdpDomainSupport* domainSupport = _GetDomain(buffer);
+       UdpDomainSupport* domainSupport = _GetDomainSupport(buffer);
        if (domainSupport == NULL) {
                // we don't instantiate domain supports in the receiving path, 
as
                // we are only interested in delivering data to existing 
sockets.
@@ -738,26 +738,24 @@
 
 
 status_t
-UdpEndpointManager::Deframe(net_buffer *buffer)
+UdpEndpointManager::Deframe(net_buffer* buffer)
 {
        TRACE_EPM("Deframe(%p [%ld bytes])", buffer, buffer->size);
 
        NetBufferHeaderReader<udp_header> bufferHeader(buffer);
-       if (bufferHeader.Status() < B_OK)
+       if (bufferHeader.Status() != B_OK)
                return bufferHeader.Status();
 
-       udp_header &header = bufferHeader.Data();
+       udp_header& header = bufferHeader.Data();
 
-       if (buffer->interface_address == NULL
-               || buffer->interface_address->domain == NULL) {
+       net_domain* domain = _GetDomain(buffer);
+       if (domain == NULL) {
                TRACE_EPM("  Deframe(): UDP packed dropped as there was no 
domain "
                        "specified (interface address %p).", 
buffer->interface_address);
                return B_BAD_VALUE;
        }
+       net_address_module_info* addressModule = domain->address_module;
 
-       net_domain *domain = buffer->interface_address->domain;
-       net_address_module_info *addressModule = domain->address_module;
-
        SocketAddress source(addressModule, buffer->source);
        SocketAddress destination(addressModule, buffer->destination);
 
@@ -799,7 +797,7 @@
 {
        MutexLocker _(fLock);
 
-       UdpDomainSupport *domain = _GetDomain(endpoint->Domain(), true);
+       UdpDomainSupport* domain = _GetDomainSupport(endpoint->Domain(), true);
        if (domain)
                domain->Ref();
        return domain;
@@ -823,19 +821,32 @@
 // #pragma mark -
 
 
-UdpDomainSupport *
-UdpEndpointManager::_GetDomain(net_domain *domain, bool create)
+inline net_domain*
+UdpEndpointManager::_GetDomain(net_buffer* buffer)
 {
-       UdpDomainList::Iterator it = fDomains.GetIterator();
+       if (buffer->interface_address != NULL)
+               return buffer->interface_address->domain;
 
+       return gStackModule->get_domain(buffer->destination->sa_family);
+}
+
+
+UdpDomainSupport*
+UdpEndpointManager::_GetDomainSupport(net_domain* domain, bool create)
+{
+       ASSERT_LOCKED_MUTEX(&fLock);
+
+       if (domain == NULL)
+               return NULL;
+
        // TODO convert this into a Hashtable or install per-domain
        //      receiver handlers that forward the requests to the
        //      appropriate DemuxIncomingBuffer(). For instance, while
        //      being constructed UdpDomainSupport could call
        //      register_domain_receiving_protocol() with the right
        //      family.
-       while (it.HasNext()) {
-               UdpDomainSupport *domainSupport = it.Next();
+       UdpDomainList::Iterator iterator = fDomains.GetIterator();
+       while (UdpDomainSupport* domainSupport = iterator.Next()) {
                if (domainSupport->Domain() == domain)
                        return domainSupport;
        }
@@ -843,8 +854,8 @@
        if (!create)
                return NULL;
 
-       UdpDomainSupport *domainSupport =
-               new (std::nothrow) UdpDomainSupport(domain);
+       UdpDomainSupport* domainSupport
+               = new (std::nothrow) UdpDomainSupport(domain);
        if (domainSupport == NULL || domainSupport->Init() < B_OK) {
                delete domainSupport;
                return NULL;
@@ -855,14 +866,16 @@
 }
 
 
+/*!    Retrieves the UdpDomainSupport object responsible for this buffer, if 
the
+       domain can be determined. This is only successful if the domain support 
is
+       already existing, ie. there must already be an endpoint for the domain.
+*/
 UdpDomainSupport*
-UdpEndpointManager::_GetDomain(net_buffer* buffer)
+UdpEndpointManager::_GetDomainSupport(net_buffer* buffer)
 {
-       if (buffer->interface_address == NULL)
-               return NULL;
+       MutexLocker _(fLock);
 
-       MutexLocker _(fLock);
-       return _GetDomain(buffer->interface_address->domain, false);
+       return _GetDomainSupport(_GetDomain(buffer), false);
                // TODO: we don't want to hold to the manager's lock during the
                // whole RX path, we may not hold an endpoint's lock with the
                // manager lock held.


Other related posts:

  • » [haiku-commits] r38365 - in haiku/trunk/src/add-ons/kernel/network/protocols: ipv4 udp - axeld