* deliver_multicast() now returns whether or not it delivered the buffer,
instead of always returning B_OK. * deliver_multicast() now takes the protocol restriction of a raw socket into account. * raw_receive_data() now correctly returns whether a buffer was delivered (due to the protocol restriction, this wasn't the case before). * ipv4_receive_data() leaked all multicast buffers. * Some minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37648 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1978fb81ee
commit
aea00dc3bc
@ -80,7 +80,8 @@ public:
|
||||
{ return fReceivedLastFragment
|
||||
&& fBytesLeft == 0; }
|
||||
|
||||
static uint32 Hash(void* _packet, const void* _key, uint32 range);
|
||||
static uint32 Hash(void* _packet, const void* _key,
|
||||
uint32 range);
|
||||
static int Compare(void* _packet, const void* _key);
|
||||
static int32 NextOffset()
|
||||
{ return offsetof(FragmentPacket, fNext); }
|
||||
@ -660,12 +661,15 @@ send_fragments(ipv4_protocol* protocol, struct net_route* route,
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
/*! Delivers the provided \a buffer to all listeners of this multicast group.
|
||||
Does not take over ownership of the buffer.
|
||||
*/
|
||||
static bool
|
||||
deliver_multicast(net_protocol_module_info* module, net_buffer* buffer,
|
||||
bool deliverToRaw)
|
||||
{
|
||||
if (module->deliver_data == NULL)
|
||||
return B_OK;
|
||||
return false;
|
||||
|
||||
MutexLocker _(sMulticastGroupsLock);
|
||||
|
||||
@ -674,32 +678,41 @@ deliver_multicast(net_protocol_module_info* module, net_buffer* buffer,
|
||||
MulticastState::ValueIterator it = sMulticastState->Lookup(std::make_pair(
|
||||
&multicastAddr->sin_addr, buffer->interface->index));
|
||||
|
||||
size_t count = 0;
|
||||
|
||||
while (it.HasNext()) {
|
||||
IPv4GroupInterface* state = it.Next();
|
||||
|
||||
if (deliverToRaw && state->Parent()->Socket()->raw == NULL)
|
||||
ipv4_protocol* ipProtocol = state->Parent()->Socket();
|
||||
if (deliverToRaw && (ipProtocol->raw == NULL
|
||||
|| ipProtocol->socket->protocol != buffer->protocol))
|
||||
continue;
|
||||
|
||||
if (state->FilterAccepts(buffer)) {
|
||||
// as Multicast filters are installed with an IPv4 protocol
|
||||
net_protocol* protocol = ipProtocol;
|
||||
if (protocol->module != module) {
|
||||
// as multicast filters are installed with an IPv4 protocol
|
||||
// reference, we need to go and find the appropriate instance
|
||||
// related to the 'receiving protocol' with module 'module'.
|
||||
net_protocol* protocol
|
||||
= state->Parent()->Socket()->socket->first_protocol;
|
||||
net_protocol* protocol = ipProtocol->socket->first_protocol;
|
||||
|
||||
while (protocol != NULL && protocol->module != module)
|
||||
protocol = protocol->next;
|
||||
}
|
||||
|
||||
if (protocol != NULL)
|
||||
if (protocol != NULL) {
|
||||
module->deliver_data(protocol, buffer);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
|
||||
/*! Delivers the buffer to all listening raw sockets.
|
||||
/*! Delivers the buffer to all listening raw sockets without taking ownership of
|
||||
the provided \a buffer.
|
||||
Returns \c true if there was any receiver, \c false if not.
|
||||
*/
|
||||
static bool
|
||||
@ -712,25 +725,28 @@ raw_receive_data(net_buffer* buffer)
|
||||
|
||||
TRACE("RawReceiveData(%i)", buffer->protocol);
|
||||
|
||||
if (buffer->flags & MSG_MCAST) {
|
||||
if ((buffer->flags & MSG_MCAST) != 0) {
|
||||
// we need to call deliver_multicast here separately as
|
||||
// buffer still has the IP header, and it won't in the
|
||||
// next call. This isn't very optimized but works for now.
|
||||
// A better solution would be to hold separate hash tables
|
||||
// and lists for RAW and non-RAW sockets.
|
||||
deliver_multicast(&gIPv4Module, buffer, true);
|
||||
} else {
|
||||
return deliver_multicast(&gIPv4Module, buffer, true);
|
||||
}
|
||||
|
||||
RawSocketList::Iterator iterator = sRawSockets.GetIterator();
|
||||
size_t count = 0;
|
||||
|
||||
while (iterator.HasNext()) {
|
||||
RawSocket* raw = iterator.Next();
|
||||
|
||||
if (raw->Socket()->protocol == buffer->protocol)
|
||||
if (raw->Socket()->protocol == buffer->protocol) {
|
||||
raw->SocketEnqueue(buffer);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1637,11 +1653,13 @@ ipv4_receive_data(net_buffer* buffer)
|
||||
}
|
||||
|
||||
if ((buffer->flags & MSG_MCAST) != 0) {
|
||||
// Unfortunely historical reasons dictate that the IP multicast
|
||||
// Unfortunately historical reasons dictate that the IP multicast
|
||||
// model be a little different from the unicast one. We deliver
|
||||
// this frame directly to all sockets registered with interest
|
||||
// for this multicast group.
|
||||
return deliver_multicast(module, buffer, false);
|
||||
deliver_multicast(module, buffer, false);
|
||||
gBufferModule->free(buffer);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return module->receive_data(buffer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user