[haiku-commits] r38118 - haiku/trunk/src/add-ons/kernel/network/stack
- From: axeld@xxxxxxxxxxxxxxxx
- To: haiku-commits@xxxxxxxxxxxxx
- Date: Sun, 15 Aug 2010 15:21:42 +0200 (CEST)
Author: axeld
Date: 2010-08-15 15:21:42 +0200 (Sun, 15 Aug 2010)
New Revision: 38118
Changeset: http://dev.haiku-os.org/changeset/38118
Ticket: http://dev.haiku-os.org/ticket/6446
Modified:
haiku/trunk/src/add-ons/kernel/network/stack/datalink.cpp
haiku/trunk/src/add-ons/kernel/network/stack/device_interfaces.cpp
Log:
* Spotted a few reference counting bugs that were probably responsible for
#6446, although I could not reproduce the exact problem.
* net_datalink::is_local_[link_]address() now releases a previous reference if
the _interfaceAddress arguments does not point to NULL.
* When a buffer is received from a device, it's interface_address should be NULL
already.
Modified: haiku/trunk/src/add-ons/kernel/network/stack/datalink.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/network/stack/datalink.cpp 2010-08-15
13:17:52 UTC (rev 38117)
+++ haiku/trunk/src/add-ons/kernel/network/stack/datalink.cpp 2010-08-15
13:21:42 UTC (rev 38118)
@@ -164,7 +164,17 @@
}
-status_t
+static void
+set_interface_address(net_interface_address*& target, InterfaceAddress*
address)
+{
+ if (target != NULL)
+ static_cast<InterfaceAddress*>(target)->ReleaseReference();
+
+ target = address;
+}
+
+
+static status_t
fill_address(const sockaddr* from, sockaddr* to, size_t maxLength)
{
if (from != NULL) {
@@ -260,7 +270,7 @@
return status;
}
-
+
case SIOCGIFCOUNT:
{
// count number of interfaces
@@ -340,7 +350,7 @@
{
TRACE("%s(route %p, buffer %p)\n", __FUNCTION__, route, buffer);
- net_interface_address* address = route->interface_address;
+ InterfaceAddress* address = (InterfaceAddress*)route->interface_address;
Interface* interface = (Interface*)address->interface;
//dprintf("send buffer (%ld bytes) to interface %s (route flags %lx)\n",
@@ -356,7 +366,8 @@
// We set the interface address here, so the buffer is delivered
// directly to the domain in
interfaces.cpp:device_consumer_thread()
- buffer->interface_address = address;
+ address->AcquireReference();
+ set_interface_address(buffer->interface_address, address);
// this one goes back to the domain directly
return fifo_enqueue_buffer(
@@ -408,7 +419,7 @@
&route);
} else
status = get_buffer_route(domain, buffer, &route);
-
+
TRACE(" route status: %s\n", strerror(status));
if (status != B_OK)
@@ -422,8 +433,10 @@
/*! Tests if \a address is a local address in the domain.
- \param _interface will be set to the interface belonging to that address
- if non-NULL.
+ \param _interfaceAddress will be set to the interface address belonging
to
+ that address if non-NULL. If the address \a _interfaceAddress
points to
+ is not NULL, it is assumed that it already points to an
address, which
+ is then released before the new address is assigned.
\param _matchedType will be set to either zero or MSG_BCAST if non-NULL.
*/
static bool
@@ -457,7 +470,7 @@
TRACE(" it is, interface address %p\n", interfaceAddress);
if (_interfaceAddress != NULL)
- *_interfaceAddress = interfaceAddress;
+ set_interface_address(*_interfaceAddress, interfaceAddress);
else
interfaceAddress->ReleaseReference();
@@ -472,7 +485,10 @@
\param unconfiguredOnly only unconfigured interfaces are taken into
account.
\param _interfaceAddress will be set to the first address of the
interface
- and domain belonging to that address if non-NULL.
+ and domain belonging to that address if non-NULL. If the address
+ \a _interfaceAddress points to is not NULL, it is assumed that
it
+ already points to an address, which is then released before the
new
+ address is assigned.
*/
static bool
datalink_is_local_link_address(net_domain* domain, bool unconfiguredOnly,
@@ -496,7 +512,7 @@
}
if (_interfaceAddress != NULL)
- *_interfaceAddress = interfaceAddress;
+ set_interface_address(*_interfaceAddress, interfaceAddress);
else
interfaceAddress->ReleaseReference();
Modified: haiku/trunk/src/add-ons/kernel/network/stack/device_interfaces.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/network/stack/device_interfaces.cpp
2010-08-15 13:17:52 UTC (rev 38117)
+++ haiku/trunk/src/add-ons/kernel/network/stack/device_interfaces.cpp
2010-08-15 13:21:42 UTC (rev 38118)
@@ -59,7 +59,8 @@
if (atomic_get(&interface->monitor_count) > 0)
device_interface_monitor_receive(interface,
buffer);
- buffer->interface_address = NULL;
+ ASSERT(buffer->interface_address == NULL);
+
if (interface->deframe_func(interface->device, buffer)
!= B_OK) {
gNetBufferModule.free(buffer);
continue;
@@ -307,7 +308,7 @@
address.sdl_alen = interface->device->address.length;
memcpy(LLADDR(&address), interface->device->address.data,
address.sdl_alen);
- address.sdl_len = sizeof(sockaddr_dl) - sizeof(address.sdl_data)
+ address.sdl_len = sizeof(sockaddr_dl) - sizeof(address.sdl_data)
+ address.sdl_nlen + address.sdl_alen;
}
Other related posts:
- » [haiku-commits] r38118 - haiku/trunk/src/add-ons/kernel/network/stack - axeld